Десериализация поля Claims в строку возвращает дополнительные символы - PullRequest
0 голосов
/ 30 сентября 2019

Мне нужно десериализовать следующую полезную нагрузку, в частности поле aud из объекта JSON:

claims: Claims { 
    aud: One("CBr3zBlrKBbwmxOAM1avZQ=="), // 24 len
    // ...
}

claims::aud - это перечисление Aud:

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Aud {
    One(String),
    Many(Vec<String>),
}

Когда я пытаюсь получить String из serde_json::to_string(), он возвращает два дополнительных символа, начальный и конечный символы.

use serde_json::Result;

fn aud_from_json(data: &claims::Aud) -> Result<String> {
    let v = serde_json::to_string(&data)?;
    Ok(v.to_owned())
}
let aud = aud_from_json(&token_data.claims.aud)?;
log::debug!("aud field: {:?}\t aud field len({})", &aud, &aud.len());
$ aud field: "\"CBr3zBlrKBbwmxOAM1avZQ==\""         aud field len(26)

Похоже, что конечные escape-символы сериализованыв строку.
Существует ли метод, который может вернуть aud поле, возвращаемое как String, очищенное без лишних символов?
например, "CBr3zBlrKBbwmxOAM1avZQ=="

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

Проблема заключалась в том, что serde_json::to_string() было ошибочно принято за фактическую реализацию to_string(), в отличие от строки JSON.

Извлечение внутреннего члена варианта enum лучше выполнить путем сопоставления с образцом,Из-за требований ФП последний aud член Vec является наиболее важным

Окончательная реализация ( детская площадка ):

use std::io::Result;
use serde;
#[macro_use] extern crate serde_derive;

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum Aud {
    One(String),
    Many(Vec<String>),
}

fn aud_from_json(data: &Aud) -> Result<String> {
    match data {
        Aud::One(audience) => Ok(audience.clone()),
        Aud::Many(audiences) => audiences
          .last()
          .ok_or(std::io::Error::new(std::io::ErrorKind::NotFound, "No audience found"))
          .map(|r| r.clone())
    }
}
0 голосов
/ 30 сентября 2019

Если я правильно понял, что вы сказали в ответ на ответ @ SébastienRenauld, вы хотите, чтобы base-64 декодировал строку, содержащуюся в экземпляре Aud. Это может быть достигнуто с помощью:

let aud = Aud::One("CBr3zBlrKBbwmxOAM1avZQ==".to_string());
if let Aud::One(code) = aud {
    let decoded = base64::decode(&code).unwrap();
    log::debug!("Decoded: {:?}", decoded);
}

детская площадка

...