Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用serde_json使用非字符串键序列化映射_Json_Rust_Serde - Fatal编程技术网

使用serde_json使用非字符串键序列化映射

使用serde_json使用非字符串键序列化映射,json,rust,serde,Json,Rust,Serde,我已经编写了一个测试用例: 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 n

我已经编写了一个测试用例:

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"}"#);
    }
}

我如何告诉serde_json使用
slend
std::fmt::Display::fmt
实现,将
slend::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"}"#);
    }
}
使用serde::{Serialize,Serializer};
#[导出(调试、部分Q、等式、部分Ord、Ord)]
结构斜坡{
上升:u8,
距离:u8,
}
内倾角{
新酒吧(上升:u8,距离:u8)->倾斜{
倾斜{上升,距离}
}
}
斜面的impl序列化{
fn序列化(&self,序列化程序:S)->结果
哪里
S:序列化程序,
{
serializer.serialize_str(&format!(“{}:{}”,self.rise,self.distance))
}
}
#[cfg(测试)]
模试验{
使用std::collections::BTreeMap;
使用超级::*;
#[测试]
fn序列化(){
让键=倾斜::新(4,3);
让value=“陡坡”;
让mut映射:BTreeMap=BTreeMap::new();
映射。插入(键、值);
让serialised=serde_json::to_string(&map).unwrap();
assert#eq!(连载,r#“{”4:3:“一座陡峭的山}”);
}
}
整体而言,序列化和反序列化如下所示:

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);
    }
}
使用serde::{Serialize,Serializer,Deserialize,Deserializer};
使用serde::de:{self,Visitor,Unexpected};
使用std::fmt;
使用std::str::FromStr;
使用regex::regex;
#[导出(调试、部分Q、等式、部分Ord、Ord)]
结构斜坡{
上升:u8,
距离:u8,
}
内倾角{
新酒吧(上升:u8,距离:u8)->倾斜{
倾斜{上升,距离}
}
}
斜面的impl序列化{
fn序列化(&self,序列化程序:S)->结果
哪里
S:序列化程序,
{
serializer.serialize_str(&format!(“{}:{}”,self.rise,self.distance))
}
}
结构倾斜器;
倾斜指示器的impl{
类型值=倾斜;
fn预期(&self,格式化程序:&mut fmt::formatter)->fmt::Result{
write_str(“0到255之间以冒号分隔的整数对”)
}
fn访问\u str(self,s:&str)->结果
哪里
E:de::错误,
{
让re=Regex::new(r“(\d+):(\d+)).unwrap();//性能:将其移动到惰性静态中!
如果让一些(nums)=重新捕获{
如果让Ok(上升)=u8::from_str(&nums[1]){//nums[0]是整个匹配,那么我们必须跳过它
如果让Ok(距离)=u8::from_str(&nums[2]){
正常(倾斜:新(上升,距离))
}否则{
Err(de::Error::无效的_值(意外的::Str和self))
}
}否则{
Err(de::Error::无效的_值(意外的::Str和self))
}
}否则{
Err(de::Error::无效的_值(意外的::Str和self))
}
}
}
倾斜{
fn反序列化(反序列化程序:D)->结果
哪里
D:反序列化程序
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);
    }
}