76 个版本
0.18.0 | 2024 年 6 月 15 日 |
---|---|
0.17.5 | 2023 年 12 月 16 日 |
0.17.4 | 2022 年 5 月 28 日 |
0.17.1 | 2022 年 2 月 17 日 |
0.1.0 | 2019 年 11 月 27 日 |
在 #edn 中排名 12
每月下载量 403
用于 5 个包
125KB
2.5K SLoC
废弃警告
该项目目前开发已暂停。没有新功能正在开发中,也没有破坏性更改。如果您有关键问题,我们可能会查看。您可能发现 Grinkers/clojure-reader
作为合适的替代品,它是由我们的维护者 @Grinkers 构建的。
edn-rs
用于解析和输出 EDN 的包 (Extensible Data Notation)
- MSRV(最低支持的 Rust 版本)是稳定版减去 2 个版本。一旦稳定(1.0.0),计划无限期维护 MSRV。
- 当前库维护者:Kevin Nakamura (@Grinkers)
完整集成示例
用法
默认
包含功能 std
和 sets
。
[dependencies]
edn-rs = "0.17.4"
no_std
要使用 edn-rs
而不带任何其他依赖项,请禁用默认功能。 edn-rs
仍然依赖于 alloc
。在 no_std 环境中,您必须提供自己的 #[global_allocator]
。
[dependencies]
edn-rs = { version = "0.17.4", default-features = false }
可选功能
std
:实现 Hashmap 和 HashSet 的序列化和反序列化;还包含一些浮点功能。sets
:实现 EDN 集的序列化和反序列化。依赖于ordered-float
。json
:实现 json→edn 和 edn→json 转换。依赖于regex
。
快速参考
使用 edn!
宏解析 EDN 令牌为 Edn
use edn_rs::{
edn, Edn, List
};
fn main() {
let edn = edn!((sym 1.2 3 false :f nil 3/4));
let expected = Edn::List(
List::new(
vec![
Edn::Symbol("sym".to_string()),
Edn::Double(1.2.into()),
Edn::Int(3),
Edn::Bool(false),
Edn::Key(":f".to_string()),
Edn::Nil,
Edn::Rational("3/4".to_string())
]
)
);
println!("{:?}", edn);
assert_eq!(edn, expected);
}
使用 Edn::from_str
解析 EDN 字符串
use edn_rs::{
set, map,
Edn, Map, Vector, Set,
};
use std::str::FromStr;
fn main() -> Result<(), String> {
let edn_str = "{:a \"2\" :b [true false] :c #{:A {:a :b} nil}}";
// std::str::FromStr
let edn: Edn = Edn::from_str(edn_str);
assert_eq!(
edn,
Edn::Map(Map::new(
map!{
":a".to_string() => Edn::Str("2".to_string()),
":b".to_string() => Edn::Vector(Vector::new(vec![Edn::Bool(true), Edn::Bool(false)])),
":c".to_string() => Edn::Set(Set::new(
set!{
Edn::Map(Map::new(map!{":a".to_string() => Edn::Key(":b".to_string())})),
Edn::Key(":A".to_string()),
Edn::Nil}))}
))
);
assert_eq!(edn[":b"][0], Edn::Bool(true));
Ok(())
}
要遍历 Edn
数据,可以使用 get
和 get_mut
use edn_rs::{
edn,
Edn, List, Map
};
fn main() {
let edn = edn!((sym 1.2 3 {false :f nil 3/4}));
println!("{:?}", edn);
assert_eq!(edn[1], edn!(1.2));
assert_eq!(edn[1], Edn::Double(1.2f64.into()));
assert_eq!(edn[3]["false"], edn!(:f));
assert_eq!(edn[3]["false"], Edn::Key(":f".to_string()));
}
使用 ednderive::Serialize
将 Rust 类型序列化为 EDN
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use edn_rs::{
map, set, hmap, hset
};
use edn_derive::Serialize;
#[derive(Debug, Clone, Serialize)]
struct ExampleEdn {
btreemap: BTreeMap<String, Vec<String>>,
btreeset: BTreeSet<i64>,
hashmap: HashMap<String, Vec<String>>,
hashset: HashSet<i64>,
tuples: (i32, bool, char),
nothing: (),
}
fn main() {
let edn = ExampleEdn {
btreemap: map!{"this is a key".to_string() => vec!["with".to_string(), "many".to_string(), "keys".to_string()]},
btreeset: set!{3i64, 4i64, 5i64},
hashmap: hmap!{"this is a key".to_string() => vec!["with".to_string(), "many".to_string(), "keys".to_string()]},
hashset: hset!{3i64},
tuples: (3i32, true, 'd'),
nothing: (),
};
println!("{}", edn_rs::to_string(edn));
// { :btreemap {:this-is-a-key [\"with\", \"many\", \"keys\"]}, :btreeset #{3, 4, 5}, :hashmap {:this-is-a-key [\"with\", \"many\", \"keys\"]}, :hashset #{3}, :tuples (3, true, \\d), :nothing nil, }
}
将字符串反序列化为 Rust 类型:
目前,您必须自己实现
Deserialize
特性。不久的将来,您将通过edn-derive
包自动实现。
use edn_rs::{Deserialize, Edn, EdnError};
#[derive(Debug, PartialEq)]
struct Person {
name: String,
age: u64,
}
impl Deserialize for Person {
fn deserialize(edn: &Edn) -> Result<Self, EdnError> {
Ok(Self {
name: edn_rs::from_edn(&edn[":name"])?,
age: edn_rs::from_edn(&edn[":age"])?,
})
}
}
fn main() -> Result<(), EdnError> {
let edn_str = "{:name \"rose\" :age 66}";
let person: Person = edn_rs::from_str(edn_str)?;
assert_eq!(
person,
Person {
name: "rose".to_string(),
age: 66,
}
);
println!("{:?}", person);
// Person { name: "rose", age: 66 }
let bad_edn_str = "{:name \"rose\" :age \"some text\"}";
let person: Result<Person, EdnError> = edn_rs::from_str(bad_edn_str);
assert_eq!(
person,
Err(EdnError::Deserialize(
"couldn't convert `some text` into `uint`".to_string()
))
);
Ok(())
}
将 EDN 类型反序列化为 Rust 类型:
- 将反序列化到
std::collections::*
是当前不安全的。
目前,您必须自己实现
Deserialize
特性。不久的将来,您将通过edn-derive
包自动实现。
use edn_rs::{map, Deserialize, Edn, EdnError, Map};
#[derive(Debug, PartialEq)]
struct Person {
name: String,
age: u64,
}
impl Deserialize for Person {
fn deserialize(edn: &Edn) -> Result<Self, EdnError> {
Ok(Self {
name: edn_rs::from_edn(&edn[":name"])?,
age: edn_rs::from_edn(&edn[":age"])?,
})
}
}
fn main() -> Result<(), EdnError> {
let edn = Edn::Map(Map::new(map! {
":name".to_string() => Edn::Str("rose".to_string()),
":age".to_string() => Edn::UInt(66)
}));
let person: Person = edn_rs::from_edn(&edn)?;
println!("{:?}", person);
// Person { name: "rose", age: 66 }
assert_eq!(
person,
Person {
name: "rose".to_string(),
age: 66,
}
);
let bad_edn = Edn::Map(Map::new(map! {
":name".to_string() => Edn::Str("rose".to_string()),
":age".to_string() => Edn::Str("some text".to_string())
}));
let person: Result<Person, EdnError> = edn_rs::from_edn(&bad_edn);
assert_eq!(
person,
Err(EdnError::Deserialize(
"couldn't convert `\"some text\"` into `uint`".to_string()
))
);
Ok(())
}
从 Json 发射 EDN 格式
- 此函数需要激活
json
功能。要启用此功能,请将以下行添加到您的Cargo.toml
依赖项中:edn-rs = { version = "0.17.4", features = ["json"] }
。
use edn_rs::json_to_edn;
fn main() {
let json = String::from(r#"{"hello": "world"}"#);
let edn = String::from(r#"{:hello "world"}"#);
println!("{:?}", json_to_edn(json.clone()));
assert_eq!(edn, json_to_edn(json));
let complex_json = String::from(r#"{
"people":
[
{
"name": "eva",
"age": 22
},
{
"name": "Julia",
"age": 32.0
}
],
"country or origin": "Brazil",
"queerentener": true,
"brain": null
}"#);
println!("{:?}", json_to_edn(complex_json.clone()).replace(" ", "").replace("\n", " "));
// "{ :people [ { :name \"eva\", :age 22 }, { :name \"Julia\", :age 32.0 } ], :country-or-origin \"Brazil\", :queerentener true, :brain nil }"
}
从类型 edn_rs::Edn
发射 JSON
- 关联方法是
to_json
,它需要激活json
功能。要启用此功能,请将以下行添加到您的Cargo.toml
依赖项中:edn-rs = { version = "0.17.4", features = ["json"] }
。
use std::str::FromStr;
fn complex_json() {
let edn = "{
:people-list [
{ :first-name \"eva\", :age 22 },
{ :first-name \"Julia\", :age 32.0 }
],
:country-or-origin \"Brazil\",
:queerentener true,
:brain nil }";
let parsed_edn : edn_rs::Edn = edn_rs::Edn::from_str(edn).unwrap();
let actual_json = parsed_edn.to_json();
let expected = String::from(
"{\"brain\": null,
\"countryOrOrigin\": \"Brazil\",
\"peopleList\": [
{\"age\": 22, \"firstName\": \"eva\"},
{\"age\": 32.0, \"firstName\": \"Julia\"}
],
\"queerentener\": true}",
);
assert_eq!(
actual_json,
expected
);
}
to_string/to_debug
to_debug
发射 Edn
类型的 Debug 版本。
use edn_rs::edn::{Edn, Vector};
let edn = Edn::Vector(Vector::new(vec![Edn::Int(5), Edn::Int(6), Edn::Int(7)]));
let expected = "Vector(Vector([Int(5), Int(6), Int(7)]))";
assert_eq!(edn.to_debug(), expected);
to_string
发射有效的 edn。
use edn_rs::edn::{Edn, Vector};
let edn = Edn::Vector(Vector::new(vec![Edn::Int(5), Edn::Int(6), Edn::Int(7)]));
let expected = "[5, 6, 7, ]";
assert_eq!(edn.to_string(), expected);
Larger to_string
example
fn complex_ok() -> Result<(), EdnError> {
use std::str::FromStr;
let edn_str = "{ :list [{:name \"rose\" :age 66 :cool true}, {:name \"josh\" :age 33 :cool false}, {:name \"eva\" :age 296 :cool true}] }";
let edn = Edn::from_str(edn_str)?;
println!("{:?}", edn.to_string());
// "{:list: [{:age 66, :cool true, :name \"rose\", }, {:age 33, :cool false, :name \"josh\", }, {:age 296, :cool true, :name \"eva\", }, ], }"
Ok(())
}
Edn-rs 当前功能
- 定义
struct
以映射 EDN 信息EdnNode
- 定义 EDN 类型,
EdnType
- 将 EDN 类型转换为原始类型:
Edn::Bool(true).into() -> true
。这是通过to_float
、to_bool
、to_int
、to_vec
实现的。 - 为
Edn
实现futures::Future
特性 - 为
Edn
实现to_string
- 为
Edn
实现to_debug
- 将 EDN 类型转换为原始类型:
- 解析 EDN 数据
from_str
- nil
""
- 字符串
"\"string\""
- 数字
"324352"
,"3442.234"
,"3/4"
- 关键字
:a
- 符号
sym-bol-s
- 向量
"[1 :2 \"d\"]"
- 列表
"(1 :2 \"d\")"
- 集合
"#{1 2 3}"
- 映射
"{:a 1 :b 2 }"
- 标签
#inst \"yyyy-mm-ddTHH:MM:ss\"
,#uuid \"<some-uuid>\"
作为字符串数据(不支持自定义读取器) - 嵌套结构
"{:a \"2\" :b [true false] :c #{:A {:a :b} nil}}"
- nil
- 相互嵌套的简单数据结构
edn!
- 向量中的向量
"[1 2 [:3 \"4\"]]"
- 向量中的集合
"[1 2 #{:3 \"4\"}]"
- 列表中的列表
"(1 2 (:3 \"4\"))"
- 列表中的集合
"'#{1 2 (:3 \"4\")}"
- 一般映射
"{:a 2 :b {:3 \"4\"}}"
,"{:a 2 :b [:3 \"4\"]}"
- 向量中的向量
- 多个简单数据结构相互嵌套(向量中的映射和集合)
- 多层嵌套数据结构(列表中的向量中的向量中的集合中的映射)
- 通过 Edn 数据导航
- 通过集合导航。通过
set_iter
实现
- 通过集合导航。通过
- JSON 到 Edn
- JSON 字符串到 EDN 字符串
- 宏处理结构体和枚举到 EDN
- 特质 Deserialize EDN 到结构体
- 特质 Serialize 结构体到 EDN
edn-derive
edn-derive
是一个用于序列化和反序列化 Edn 值的 proc-macro 库,目前处于 测试版 阶段,可以在 crates.io
或 github
找到。
用法
只需将以下内容添加到您的 Cargo.toml
文件中:
[dependencies]
edn-derive = "<version>"
edn-rs = "0.17.4"
示例
序列化
use edn_derive::Serialize;
#[derive(Serialize)]
pub struct Person {
name: String,
age: u64,
}
fn main() {
let person = Person {
name: "joana".to_string(),
age: 290000,
};
assert_eq!(
edn_rs::to_string(person),
"{ :name \"joana\", :age 290000, }"
);
}
反序列化
use edn_derive::Deserialize;
use edn_rs::EdnError;
// The `Debug` and `PartialEq` are only necessary because of `assert_eq`, you don't need them
#[derive(Deserialize, Debug, PartialEq)]
pub struct Person {
name: String,
age: u64,
}
fn main() -> Result<(), EdnError> {
let edn_person = "{ :name \"joana\", :age 290000, }";
let person: Person = edn_rs::from_str(edn_person)?;
assert_eq!(
person,
Person {
name: "joana".to_string(),
age: 290000,
}
);
Ok(())
}
当前功能
-
derive Serialize
-
edn_rs::to_string
-
derive Deserialize
-
letval:YourStruct= edn_rs::from_str(&str)
依赖
~0–540KB