#枚举 #字符串 #serde #序列化 #过程宏

无 std serde_string_enum

用于 serde 序列化和反序列化字符串编码枚举的过程宏

3 个不稳定版本

0.2.1 2023年8月8日
0.2.0 2023年8月8日
0.1.0 2023年8月6日

#610#枚举

Download history 20/week @ 2024-04-03 4/week @ 2024-05-15 20/week @ 2024-05-22 9/week @ 2024-05-29 24/week @ 2024-06-05 19/week @ 2024-06-12 2/week @ 2024-06-19 7/week @ 2024-07-10 62/week @ 2024-07-17

每月下载量:69
用于 battler

MIT 许可证

20KB
326 行代码(不包括注释)

serde_string_enum

Latest Version

此包提供了一种过程宏,可以自动为应编码为单个字符串的枚举类型派生 serde 的 SerializeDeserialize 特性。

[dependencies]
serde = "1.0"
serde_string_enum = "0.2"
unicase = "2.6.0"

用法

此包定义了两对宏

  • SerializeLabeledStringEnum / DeserializeLabeledStringEnum - 在每个枚举变体上使用 #[string = ...] 属性以执行字符串转换。
  • SerializeStringEnum / DeserializeStringEnum - 使用枚举类型的 DisplayFromStr 实现来执行字符串转换。

功能

  • default - std, unicase
  • std - 依赖 Rust 标准库。
  • alloc - 不依赖 Rust 标准库依赖 alloc 库。
  • unicase - 依赖 unicase 包进行 Unicode 不敏感匹配。

示例

带标签的字符串

#[cfg(feature = "alloc")]
extern crate alloc;

use serde_string_enum::{
    DeserializeLabeledStringEnum,
    SerializeLabeledStringEnum,
};

#[derive(Debug, PartialEq, SerializeLabeledStringEnum, DeserializeLabeledStringEnum)]
enum Type {
    #[string = "Grass"]
    Grass,
    #[string = "Fire"]
    #[alias = "Flame"]
    Fire,
    #[string = "Water"]
    Water,
}

fn main() -> serde_json::Result<()> {
    let j = serde_json::to_string(&Type::Grass)?;
    assert_eq!(j, "\"Grass\"");
    let t: Type = serde_json::from_str(&j)?;
    assert_eq!(t, Type::Grass);

    // Alias strings.
    let t: Type = serde_json::from_str("\"Flame\"")?;
    assert_eq!(t, Type::Fire);

    // Case-insensitive conversion also works.
    if cfg!(feature = "unicase") {
        let t: Type = serde_json::from_str("\"water\"")?;
        assert_eq!(t, Type::Water);
    }

    Ok(())
}

具有 Display 和 FromStr 的枚举

use core::{
    fmt::Display,
    str::FromStr,
};
use serde_string_enum::{
    DeserializeStringEnum,
    SerializeStringEnum,
};

#[derive(Debug, PartialEq, SerializeStringEnum, DeserializeStringEnum)]
enum Move {
    Stay,
    Forward(u8),
    Left(u8),
}

impl Display for Move {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self {
            Self::Stay => write!(f, "S"),
            Self::Forward(n) => write!(f, "F{n}"),
            Self::Left(n) => write!(f, "L{n}"),
        }
    }
}

impl FromStr for Move {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match &s[0..1] {
            "S" => Self::Stay,
            "F" => Self::Forward(s[1..].parse::<u8>().map_err(|err| err.to_string())?),
            "L" => Self::Left(s[1..].parse::<u8>().map_err(|err| err.to_string())?),
            _ => return Err(format!("invalid move {s}")),
        })
    }
}

fn main() -> serde_json::Result<()> {
    let j = serde_json::to_string(&Move::Forward(10))?;
    assert_eq!(j, "\"F10\"");
    let m: Move = serde_json::from_str(&j)?;
    assert_eq!(m, Move::Forward(10));

    let moves: Vec<Move> = serde_json::from_str("[\"S\",\"F2\",\"S\",\"L4\"]")?;
    assert_eq!(
        moves,
        vec![Move::Stay, Move::Forward(2), Move::Stay, Move::Left(4)]
    );

    Ok(())
}

依赖项

~0.5–1MB
~25K SLoC