Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,103 @@
|
||||
// 使用 auth 样例实际生成的 RestCreate0;独立 Rust 直接复用 Serde,合同相同。
|
||||
// 测量仅包含请求对象解码,不包括字段业务约束、认证、SQL 或网络。
|
||||
use dever_runtime::wire::serde::{self, Deserialize};
|
||||
use dever_runtime::wire::serde_json;
|
||||
|
||||
fn fault(_: impl std::fmt::Display) -> Fault {
|
||||
&FaultInfo { message: "REST input failure", source: "rest-reference", line: 1, column: 1 }
|
||||
}
|
||||
|
||||
enum Status { Active, Disabled }
|
||||
|
||||
impl<'input> Deserialize<'input> for Status {
|
||||
fn deserialize<Decoder: serde::Deserializer<'input>>(decoder: Decoder) -> Result<Self, Decoder::Error> {
|
||||
struct Choice;
|
||||
impl<'input> serde::de::Visitor<'input> for Choice {
|
||||
type Value = Status;
|
||||
fn expecting(&self, output: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { output.write_str("a status name") }
|
||||
fn visit_str<Error: serde::de::Error>(self, value: &str) -> Result<Status, Error> {
|
||||
match value {
|
||||
"Active" => Ok(Status::Active),
|
||||
"Disabled" => Ok(Status::Disabled),
|
||||
_ => Err(Error::custom("unknown status")),
|
||||
}
|
||||
}
|
||||
}
|
||||
decoder.deserialize_str(Choice)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(crate = "dever_runtime::wire::serde", deny_unknown_fields)]
|
||||
struct Profile {
|
||||
name: String,
|
||||
bio: Option<String>,
|
||||
#[serde(default = "rank")]
|
||||
rank: i64,
|
||||
#[serde(default = "tag")]
|
||||
tag: Option<String>,
|
||||
#[serde(default = "status")]
|
||||
status: Status,
|
||||
}
|
||||
|
||||
fn rank() -> i64 { 7 }
|
||||
fn tag() -> Option<String> { Some("automatic".into()) }
|
||||
fn status() -> Status { Status::Active }
|
||||
|
||||
fn generated(values: &[String]) -> Result<String, Fault> {
|
||||
let Some(source) = values.first() else { return Ok(String::new()); };
|
||||
let value: RestCreate0 = REST_DECODER(source).map_err(fault)?;
|
||||
Ok(value.field0)
|
||||
}
|
||||
|
||||
fn reference(values: &[String]) -> Result<String, Fault> {
|
||||
let Some(source) = values.first() else { return Ok(String::new()); };
|
||||
if source.len() > 16 * 1024 * 1024 { return Err(fault("byte limit")); }
|
||||
struct Object;
|
||||
impl<'input> serde::de::Visitor<'input> for Object {
|
||||
type Value = Profile;
|
||||
fn expecting(&self, output: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
output.write_str("an object")
|
||||
}
|
||||
fn visit_map<Access: serde::de::MapAccess<'input>>(self, access: Access) -> Result<Profile, Access::Error> {
|
||||
Profile::deserialize(serde::de::value::MapAccessDeserializer::new(access))
|
||||
}
|
||||
}
|
||||
let mut decoder = serde_json::Deserializer::from_str(source);
|
||||
let value = serde::Deserializer::deserialize_map(&mut decoder, Object).map_err(fault)?;
|
||||
decoder.end().map_err(fault)?;
|
||||
// 固定五个标量字段,类型已证明层数和值数;保留其正常构造与释放。
|
||||
let Profile { name, bio, rank, tag, status } = value;
|
||||
drop((bio, rank, tag, status));
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("workload,sample,implementation,nanos,checksum");
|
||||
for source in [
|
||||
r#"{"name":"Dever"}"#,
|
||||
r#"{"name":"Dever","bio":null,"tag":null,"status":"Disabled"}"#,
|
||||
] {
|
||||
assert_eq!(generated(&[source.into()]).unwrap(), "Dever");
|
||||
assert_eq!(reference(&[source.into()]).unwrap(), "Dever");
|
||||
}
|
||||
for source in [
|
||||
"[]", "null", "{}", r#"{"name":"x","name":"y"}"#,
|
||||
r#"{"name":"x","na\u006de":"y"}"#, r#"{"name":"x","extra":1}"#,
|
||||
r#"{"name":"x","rank":null}"#, r#"{"name":"x","status":"Other"}"#,
|
||||
r#"{"name":"x","status":{"Active":null}}"#,
|
||||
r#"{"name":"x","bio":"\ud800"}"#, r#"{"name":"x"} null"#,
|
||||
] {
|
||||
assert!(generated(&[source.into()]).is_err(), "{source}");
|
||||
assert!(reference(&[source.into()]).is_err(), "{source}");
|
||||
}
|
||||
for (name, bio) in [
|
||||
("short", "x".repeat(16)),
|
||||
("plain_4096", "x".repeat(4096)),
|
||||
("plain_65536", "x".repeat(65536)),
|
||||
("escaped", "雪\"\\\n".repeat(1024)),
|
||||
] {
|
||||
let input = vec![serde_json::json!({"name":"Dever","bio":bio,"rank":7,"tag":"automatic","status":"Active"}).to_string()];
|
||||
compare(&format!("rest_input_{name}"), &input, 1000, generated, reference, |name| name.len() as u64);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user