serde_json을 사용하여 문자열이 아닌 키로 맵 직렬화

페이드 비

테스트 케이스를 작성했습니다.

use serde::{Serialize, Deserialize};
use std::collections::BTreeMap;
use std::fmt;

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Incline {
    rise: u8,
    distance: u8,
}

impl Incline {
    pub fn new(rise: u8, distance: u8) -> Incline {
        Incline {rise, distance}
    }
}

impl fmt::Display for Incline {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{}", self.rise, self.distance)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn display_format() {
        let incline = Incline::new(4, 3);
        assert_eq!(format!("{}", incline), "4:3");
    }

    #[test]
    fn serialisation() {
        let key = Incline::new(4, 3);
        let value = "a steep hill";

        let mut map: BTreeMap<Incline, &str> = BTreeMap::new();
        map.insert(key, value);
        let serialised = serde_json::to_string(&map).unwrap();

        assert_eq!(serialised, r#"{"4:3":"a steep hill"}"#);
    }
}

display_format예상대로 시험을 통과한다.

serialisation테스트는 오류와 함께 실패합니다 :

thread 'tests::serialisation' panicked at 'called `Result::unwrap()` on an `Err` value: Error("key must be a string", line: 0, column: 0)', src/lib.rs:40:54

어떻게 사용에 serde_json 알 수 있습니까 Incline구현의 std::fmt::Display::fmt회전하는 Incline::new(4,3)로를 "4:3"?

페이드 비

좀 더 검색을 해보니 직렬화를 직접 구현해야한다는 것을 깨달았습니다.

이것은 일을합니다 :

use serde::{Serialize, Serializer};

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Incline {
    rise: u8,
    distance: u8,
}

impl Incline {
    pub fn new(rise: u8, distance: u8) -> Incline {
        Incline {rise, distance}
    }
}

impl Serialize for Incline {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&format!("{}:{}", self.rise, self.distance))
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;
    use super::*;

    #[test]
    fn serialisation() {
        let key = Incline::new(4, 3);
        let value = "a steep hill";

        let mut map: BTreeMap<Incline, &str> = BTreeMap::new();
        map.insert(key, value);
        let serialised = serde_json::to_string(&map).unwrap();

        assert_eq!(serialised, r#"{"4:3":"a steep hill"}"#);
    }
}

전체적으로 직렬화 및 역 직렬화는 다음과 같습니다.

use serde::{Serialize, Serializer, Deserialize, Deserializer};
use serde::de::{self, Visitor, Unexpected};
use std::fmt;
use std::str::FromStr;
use regex::Regex;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Incline {
    rise: u8,
    distance: u8,
}

impl Incline {
    pub fn new(rise: u8, distance: u8) -> Incline {
        Incline {rise, distance}
    }
}

impl Serialize for Incline {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&format!("{}:{}", self.rise, self.distance))
    }
}

struct InclineVisitor;

impl<'de> Visitor<'de> for InclineVisitor {
    type Value = Incline;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("a colon-separated pair of integers between 0 and 255")
    }

    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        let re = Regex::new(r"(\d+):(\d+)").unwrap(); // PERF: move this into a lazy_static!
        if let Some(nums) = re.captures_iter(s).next() {
            if let Ok(rise) = u8::from_str(&nums[1]) { // nums[0] is the whole match, so we must skip that
                if let Ok(distance) = u8::from_str(&nums[2]) {
                    Ok(Incline::new(rise, distance))
                } else {
                    Err(de::Error::invalid_value(Unexpected::Str(s), &self))
                }
            } else {
                Err(de::Error::invalid_value(Unexpected::Str(s), &self))
            }
        } else {
            Err(de::Error::invalid_value(Unexpected::Str(s), &self))
        }
    }

}

impl<'de> Deserialize<'de> for Incline {
    fn deserialize<D>(deserializer: D) -> Result<Incline, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_string(InclineVisitor)
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;
    use super::*;

    #[test]
    fn serialisation() {
        let key = Incline::new(4, 3);
        let value = "a steep hill";

        let mut map: BTreeMap<Incline, &str> = BTreeMap::new();
        map.insert(key, value);
        let serialised = serde_json::to_string(&map).unwrap();

        assert_eq!(serialised, r#"{"4:3":"a steep hill"}"#);
    }

    #[test]
    fn deserialisation() {
        let json = r#"{"4:3":"a steep hill"}"#;

        let deserialised: BTreeMap<Incline, &str> = serde_json::from_str(&json).unwrap();

        let key = Incline::new(4, 3);
        let value = "a steep hill";

        let mut map: BTreeMap<Incline, &str> = BTreeMap::new();
        map.insert(key, value);

        assert_eq!(deserialised, map);
    }
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

serde_json을 사용하여 내부 열거 형 값을 & str에서 u64로 역 직렬화

분류에서Dev

IllegalStateException-Gson을 사용하여 문자열 배열로 맵 직렬화

분류에서Dev

Java 맵에서 ASCII가 아닌 문자열을 키로 사용하는 동안 값이 없음

분류에서Dev

serde_cbor를 사용하여 Rust에서 Vec <u8>을 CBOR 바이트 문자열로 직렬화

분류에서Dev

Newtonsoft.JSON을 사용하여 C #으로 Json 문자열 역 직렬화

분류에서Dev

serde_json을 엄격하게 역 직렬화하는 방법이 있습니까?

분류에서Dev

serde를 사용하여 JSON 배열을 구조체로 역 직렬화하는 방법은 무엇입니까?

분류에서Dev

C # 문자열로 시작하는 키 이름으로 JSON 역 직렬화

분류에서Dev

스칼라는 목록을 키로, 문자열을 값으로 사용하여 맵을 평면화합니다.

분류에서Dev

C ++에서 MessagePack을 사용하여 이기종 맵 역 직렬화

분류에서Dev

형식 패턴을 사용하여 문자열을 값으로 역 직렬화

분류에서Dev

Newtonsoft.Json 라이브러리를 사용하여 문자열을 C #을 사용하여 사용자 지정 개체로 역 직렬화하는 방법

분류에서Dev

System.Text.Json.JsonSerializer는 원시 값이 아닌 사전 키를 직렬화 할 때 DictionaryKeyPolicy를 무시합니다.

분류에서Dev

Regex를 사용하여 문자열 내부의 직렬화 문자열을 폭발시키는 방법

분류에서Dev

enum을 전역 적으로 문자열로 직렬화하는 방법 (각 enum의 속성이 아니라)?

분류에서Dev

Jackson으로 사용자 지정 맵 직렬화

분류에서Dev

Jackson을 사용하여 부울을 JSON으로 문자열로 직렬화하는 방법

분류에서Dev

변수 이름을 사용하여 개체로 역 직렬화

분류에서Dev

Jackson 2-Android에서 Retrofit REST-API를 사용하여 문자열을 날짜로 직접 역 직렬화

분류에서Dev

PHP를 사용하여 배열 (배열에서 쿼리 문자열로)을 직렬화하는 방법

분류에서Dev

kotlinx.serialization을 사용하여 json 객체 속성을 문자열로 역 직렬화

분류에서Dev

Json.NET을 사용하여 DateTimeOffset을 zulu 시간 문자열로 직렬화 할 수 있습니까?

분류에서Dev

직렬화 데이터 (JSON)를 입력으로 사용하여 그리드 스터 레이아웃 빌드

분류에서Dev

Presto : 맵과 비슷하지만 맵이 아닌 문자열 열에서 값을 추출합니다.

분류에서Dev

유형 식별자로 숫자 값으로 serde를 사용하여 json의 역 직렬화

분류에서Dev

JSON 문자열을 객체로 역 직렬화하는 방법

분류에서Dev

C # Content로 이미 직렬화 된 문자열을 직렬화하지 않는 방법

분류에서Dev

안드로이드 정규식을 사용하여 문자열에서 숫자가 아닌 문자를 일치시키는 방법은 무엇입니까?

분류에서Dev

Jackson을 사용하여 JSON 배열을 매핑으로 역 직렬화

Related 관련 기사

  1. 1

    serde_json을 사용하여 내부 열거 형 값을 & str에서 u64로 역 직렬화

  2. 2

    IllegalStateException-Gson을 사용하여 문자열 배열로 맵 직렬화

  3. 3

    Java 맵에서 ASCII가 아닌 문자열을 키로 사용하는 동안 값이 없음

  4. 4

    serde_cbor를 사용하여 Rust에서 Vec <u8>을 CBOR 바이트 문자열로 직렬화

  5. 5

    Newtonsoft.JSON을 사용하여 C #으로 Json 문자열 역 직렬화

  6. 6

    serde_json을 엄격하게 역 직렬화하는 방법이 있습니까?

  7. 7

    serde를 사용하여 JSON 배열을 구조체로 역 직렬화하는 방법은 무엇입니까?

  8. 8

    C # 문자열로 시작하는 키 이름으로 JSON 역 직렬화

  9. 9

    스칼라는 목록을 키로, 문자열을 값으로 사용하여 맵을 평면화합니다.

  10. 10

    C ++에서 MessagePack을 사용하여 이기종 맵 역 직렬화

  11. 11

    형식 패턴을 사용하여 문자열을 값으로 역 직렬화

  12. 12

    Newtonsoft.Json 라이브러리를 사용하여 문자열을 C #을 사용하여 사용자 지정 개체로 역 직렬화하는 방법

  13. 13

    System.Text.Json.JsonSerializer는 원시 값이 아닌 사전 키를 직렬화 할 때 DictionaryKeyPolicy를 무시합니다.

  14. 14

    Regex를 사용하여 문자열 내부의 직렬화 문자열을 폭발시키는 방법

  15. 15

    enum을 전역 적으로 문자열로 직렬화하는 방법 (각 enum의 속성이 아니라)?

  16. 16

    Jackson으로 사용자 지정 맵 직렬화

  17. 17

    Jackson을 사용하여 부울을 JSON으로 문자열로 직렬화하는 방법

  18. 18

    변수 이름을 사용하여 개체로 역 직렬화

  19. 19

    Jackson 2-Android에서 Retrofit REST-API를 사용하여 문자열을 날짜로 직접 역 직렬화

  20. 20

    PHP를 사용하여 배열 (배열에서 쿼리 문자열로)을 직렬화하는 방법

  21. 21

    kotlinx.serialization을 사용하여 json 객체 속성을 문자열로 역 직렬화

  22. 22

    Json.NET을 사용하여 DateTimeOffset을 zulu 시간 문자열로 직렬화 할 수 있습니까?

  23. 23

    직렬화 데이터 (JSON)를 입력으로 사용하여 그리드 스터 레이아웃 빌드

  24. 24

    Presto : 맵과 비슷하지만 맵이 아닌 문자열 열에서 값을 추출합니다.

  25. 25

    유형 식별자로 숫자 값으로 serde를 사용하여 json의 역 직렬화

  26. 26

    JSON 문자열을 객체로 역 직렬화하는 방법

  27. 27

    C # Content로 이미 직렬화 된 문자열을 직렬화하지 않는 방법

  28. 28

    안드로이드 정규식을 사용하여 문자열에서 숫자가 아닌 문자를 일치시키는 방법은 무엇입니까?

  29. 29

    Jackson을 사용하여 JSON 배열을 매핑으로 역 직렬화

뜨겁다태그

보관