Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,130 @@
|
||||
// 两侧都接收已验证的 JSON,返回独立拥有的原始子树;不在计时内重复验证输入。
|
||||
// 独立参照只使用 Serde,不调用 Dever 的键比较或字段读取实现。
|
||||
use dever_runtime::wire::serde::{
|
||||
Deserializer,
|
||||
de::{DeserializeSeed, IgnoredAny, MapAccess, Visitor},
|
||||
};
|
||||
use dever_runtime::wire::serde_json::{self, value::RawValue};
|
||||
|
||||
struct PropertyCase {
|
||||
source: Json,
|
||||
name: String,
|
||||
}
|
||||
|
||||
struct MatchingKey<'name>(&'name str);
|
||||
|
||||
impl<'input> DeserializeSeed<'input> for MatchingKey<'_> {
|
||||
type Value = bool;
|
||||
|
||||
fn deserialize<Decoder: Deserializer<'input>>(
|
||||
self,
|
||||
decoder: Decoder,
|
||||
) -> Result<bool, Decoder::Error> {
|
||||
decoder.deserialize_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'input> Visitor<'input> for MatchingKey<'_> {
|
||||
type Value = bool;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
formatter.write_str("an object key")
|
||||
}
|
||||
|
||||
fn visit_str<Failure: dever_runtime::wire::serde::de::Error>(
|
||||
self,
|
||||
value: &str,
|
||||
) -> Result<bool, Failure> {
|
||||
Ok(value == self.0)
|
||||
}
|
||||
}
|
||||
|
||||
struct MatchingProperty<'name>(&'name str);
|
||||
|
||||
impl<'input> Visitor<'input> for MatchingProperty<'_> {
|
||||
type Value = Option<&'input RawValue>;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
formatter.write_str("an object")
|
||||
}
|
||||
|
||||
fn visit_map<Access: MapAccess<'input>>(
|
||||
self,
|
||||
mut fields: Access,
|
||||
) -> Result<Self::Value, Access::Error> {
|
||||
let mut result = None;
|
||||
while let Some(matches) = fields.next_key_seed(MatchingKey(self.0))? {
|
||||
if matches {
|
||||
result = Some(fields.next_value()?);
|
||||
} else {
|
||||
fields.next_value::<IgnoredAny>()?;
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
fn runtime_property(values: &[PropertyCase]) -> Result<Option<String>, Fault> {
|
||||
let Some(value) = values.first() else {
|
||||
return Ok(None);
|
||||
};
|
||||
value
|
||||
.source
|
||||
.property(&value.name)
|
||||
.map(|found| found.map(Json::into_text))
|
||||
.map_err(json_fault)
|
||||
}
|
||||
|
||||
fn native_property(values: &[PropertyCase]) -> Result<Option<String>, Fault> {
|
||||
let Some(value) = values.first() else {
|
||||
return Ok(None);
|
||||
};
|
||||
let mut decoder =
|
||||
dever_runtime::wire::serde_json::Deserializer::from_str(value.source.as_str());
|
||||
decoder
|
||||
.deserialize_map(MatchingProperty(&value.name))
|
||||
.map(|found| found.map(|raw| raw.get().to_owned()))
|
||||
.map_err(json_fault)
|
||||
}
|
||||
|
||||
fn property_costs() {
|
||||
for (kind, suffix) in [("plain", ""), ("escaped", "雪\\\"\n")] {
|
||||
let names = (0..256)
|
||||
.map(|index| format!("key_{index:03}_{suffix}"))
|
||||
.collect::<Vec<_>>();
|
||||
let fields = names
|
||||
.iter()
|
||||
.map(|name| {
|
||||
format!(
|
||||
"{}: [ 1e9999, -0, \"\\u96ea\" ]",
|
||||
serde_json::to_string(name).unwrap()
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let source = format!("{{{}}}", fields.join(","));
|
||||
for (position, name) in [
|
||||
("first", names[0].as_str()),
|
||||
("middle", names[128].as_str()),
|
||||
("last", names[255].as_str()),
|
||||
("missing", "absent"),
|
||||
] {
|
||||
let values = [PropertyCase {
|
||||
source: Json::parse(&source).unwrap(),
|
||||
name: name.into(),
|
||||
}];
|
||||
let expected =
|
||||
(position != "missing").then(|| r#"[ 1e9999, -0, "\u96ea" ]"#.to_owned());
|
||||
assert_eq!(runtime_property(&values).unwrap(), expected);
|
||||
assert_eq!(native_property(&values).unwrap(), expected);
|
||||
compare_named(
|
||||
&format!("json_property_{kind}_{position}"),
|
||||
&values,
|
||||
1000,
|
||||
runtime_property,
|
||||
native_property,
|
||||
|value| value.as_ref().map_or(0, |text| text.len() as u64),
|
||||
"rust_serde",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user