Files
core/test/rust/performance/application/rest.rs
T
2026-11-03 03:32:07 +00:00

104 lines
4.2 KiB
Rust

// 使用 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);
}
}