Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

@@ -0,0 +1,266 @@
use dever_runtime::async_stream::AsyncStream;
use dever_runtime::channel::Channel;
use dever_runtime::task::{Group, Limits, Runtime, Scope, Task};
struct ConcurrencyCase {
runtime: Runtime,
values: Vec<i64>,
limit: i64,
}
fn concurrency_fault() -> Fault {
&FaultInfo {
message: "extended concurrency failed",
source: "extended-concurrency-reference",
line: 1,
column: 1,
}
}
type ChannelOutput = (Vec<Option<i64>>, bool);
fn channel_generated(values: &[ConcurrencyCase]) -> Result<ChannelOutput, Fault> {
let Some(value) = values.first() else {
return Ok((Vec::new(), true));
};
value
.runtime
.run(async |scope| EXT_CHANNEL(&value.values, value.limit, scope).await)
.map_err(|_| concurrency_fault())?
.map_err(|_| concurrency_fault())
}
async fn send_values(values: Vec<i64>, channel: Channel<i64>) -> Result<(), Fault> {
for value in values {
channel.send(value).await.map_err(|_| concurrency_fault())?;
}
channel.close().await.map_err(|_| concurrency_fault())
}
fn channel_reference(values: &[ConcurrencyCase]) -> Result<ChannelOutput, Fault> {
let Some(value) = values.first() else {
return Ok((Vec::new(), true));
};
value
.runtime
.run(async |scope| {
let channel = Channel::new(value.limit).map_err(|_| concurrency_fault())?;
let producer = channel.clone();
let owned = value.values.clone();
let pending = scope
.spawn_leaf(move || send_values(owned, producer))
.map_err(|_| concurrency_fault())?;
let mut received = Vec::with_capacity(value.values.len());
for _ in &value.values {
received.push(channel.receive().await.map_err(|_| concurrency_fault())?);
}
pending.wait().await.map_err(|_| concurrency_fault())??;
let ended = channel
.receive()
.await
.map_err(|_| concurrency_fault())?
.is_none();
Ok((received, ended))
})
.map_err(|_| concurrency_fault())?
}
fn channel_score(value: &ChannelOutput) -> u64 {
value.0.iter().fold(u64::from(value.1), |score, item| {
score
.wrapping_mul(31)
.wrapping_add(item.unwrap_or(0) as u64)
})
}
async fn stream_total(stream: &AsyncStream<i64>, limit: Option<i64>) -> Result<i64, Fault> {
let _close = stream.close_on_drop();
let mut total = 0i64;
while let Some(value) = stream.next().await.map_err(|_| concurrency_fault())? {
total = total.checked_add(value).ok_or_else(concurrency_fault)?;
if limit.is_some_and(|limit| value >= limit) {
break;
}
}
Ok(total)
}
fn pull_generated(values: &[ConcurrencyCase]) -> Result<(i64, i64), Fault> {
let Some(value) = values.first() else {
return Ok((0, 0));
};
value
.runtime
.run_leaf(EXT_PULL(&value.values))
.map_err(|_| concurrency_fault())?
.map_err(|_| concurrency_fault())
}
fn prefix_generated(values: &[ConcurrencyCase]) -> Result<(i64, i64), Fault> {
let Some(value) = values.first() else {
return Ok((0, 0));
};
value
.runtime
.run_leaf(EXT_PREFIX(&value.values))
.map_err(|_| concurrency_fault())?
.map_err(|_| concurrency_fault())
}
fn stream_reference<const EARLY: bool>(values: &[ConcurrencyCase]) -> Result<(i64, i64), Fault> {
let Some(value) = values.first() else {
return Ok((0, 0));
};
value
.runtime
.run_leaf(async {
let stream = AsyncStream::values(value.values.clone());
let alias = stream.clone();
let total = stream_total(&stream, EARLY.then_some(8)).await?;
let after = stream_total(&alias, None).await?;
Ok((total, after))
})
.map_err(|_| concurrency_fault())?
}
fn stream_score(value: &(i64, i64)) -> u64 {
(value.0 as u64)
.wrapping_mul(31)
.wrapping_add(value.1 as u64)
}
async fn parallel_reference_inner(value: &ConcurrencyCase, scope: &Scope<'_>) -> Result<i64, Fault> {
let channel = Channel::new(1).map_err(|_| concurrency_fault())?;
let consumer = channel.clone();
let pending = scope
.spawn_leaf(
move || async move { stream_total(&AsyncStream::channel(consumer), None).await },
)
.map_err(|_| concurrency_fault())?;
let mut items = value.values.iter().copied();
let group: Group<Task<Result<(), Fault>>, Fault> =
Group::new(value.limit).map_err(|_| concurrency_fault())?;
group
.each(
|| std::future::ready(Ok(items.next())),
|item| {
let target = channel.clone();
scope.spawn_leaf(move || async move {
target.send(item).await.map_err(|_| concurrency_fault())
})
},
)
.await
.map_err(|_| concurrency_fault())??;
channel.close().await.map_err(|_| concurrency_fault())?;
pending.wait().await.map_err(|_| concurrency_fault())?
}
fn parallel_generated(values: &[ConcurrencyCase]) -> Result<i64, Fault> {
let Some(value) = values.first() else {
return Ok(0);
};
value
.runtime
.run(async |scope| EXT_PARALLEL(&value.values, value.limit, scope).await)
.map_err(|_| concurrency_fault())?
.map_err(|_| concurrency_fault())
}
fn parallel_reference(values: &[ConcurrencyCase]) -> Result<i64, Fault> {
let Some(value) = values.first() else {
return Ok(0);
};
value
.runtime
.run(async |scope| parallel_reference_inner(value, scope).await)
.map_err(|_| concurrency_fault())?
}
fn new_case(limit: i64) -> ConcurrencyCase {
ConcurrencyCase {
runtime: Runtime::new(Limits {
threads: 2,
workers: 2,
tasks: 8,
})
.unwrap(),
values: (1..=256).collect(),
limit,
}
}
fn main() {
// 两侧共用运行库与固定限额;计时含复制、提交、领取及作用域清理。
let mut case = new_case(1);
assert_eq!(
case.runtime.run_leaf(EXT_BOUNDARY()).unwrap().unwrap(),
(15, Some(9), 0)
);
let expected = case.values.iter().sum::<i64>();
println!("case,sample,implementation,elapsed_ns,checksum");
for capacity in [1, 64] {
case.limit = capacity;
let values = std::slice::from_ref(&case);
let received = case.values.iter().copied().map(Some).collect::<Vec<_>>();
assert_eq!(channel_generated(values).unwrap(), (received.clone(), true));
assert_eq!(channel_reference(values).unwrap(), (received, true));
compare_named(
&format!("channel_capacity_{capacity}_shared_runtime"),
values,
32,
channel_generated,
channel_reference,
channel_score,
"rust_runtime",
);
}
case.limit = 8;
let values = std::slice::from_ref(&case);
assert_eq!(pull_generated(values).unwrap(), (expected, 0));
assert_eq!(prefix_generated(values).unwrap(), (36, 0));
compare_named(
"async_stream_pull_shared_runtime",
values,
128,
pull_generated,
stream_reference::<false>,
stream_score,
"rust_runtime",
);
compare_named(
"async_stream_prefix_shared_runtime",
values,
128,
prefix_generated,
stream_reference::<true>,
stream_score,
"rust_runtime",
);
for limit in [1, 4] {
case.limit = limit;
let values = std::slice::from_ref(&case);
assert_eq!(parallel_generated(values).unwrap(), expected);
assert_eq!(parallel_reference(values).unwrap(), expected);
compare_named(
&format!("parallel_each_limit_{limit}_shared_runtime"),
values,
32,
parallel_generated,
parallel_reference,
|value| *value as u64,
"rust_runtime",
);
}
// 真正调用空输入 fixture,区别于 samples 的空用例切片。
case.values.clear();
let empty = std::slice::from_ref(&case);
assert_eq!(channel_generated(empty).unwrap(), (Vec::new(), true));
assert_eq!(channel_reference(empty).unwrap(), (Vec::new(), true));
assert_eq!(pull_generated(empty).unwrap(), (0, 0));
assert_eq!(prefix_generated(empty).unwrap(), (0, 0));
assert_eq!(stream_reference::<false>(empty).unwrap(), (0, 0));
assert_eq!(stream_reference::<true>(empty).unwrap(), (0, 0));
assert_eq!(parallel_generated(empty).unwrap(), 0);
assert_eq!(parallel_reference(empty).unwrap(), 0);
}
+45
View File
@@ -0,0 +1,45 @@
use std::path::Path;
pub fn run(core: &Path) -> bool {
let all = std::env::args().any(|argument| argument == "--extended");
let primitives = all || std::env::args().any(|argument| argument == "--extended-primitives");
let concurrency = all || std::env::args().any(|argument| argument == "--extended-concurrency");
if primitives {
crate::compare(
core,
"extended-performance/primitives",
"extended-primitives",
&[include_str!("../samples.rs"), include_str!("primitives.rs")].concat(),
&[
("EXT_SHA256", "sha256Digest"),
("EXT_HMAC", "hmacDigest"),
("EXT_DATETIME", "datetimeBatch"),
("EXT_DATE", "dateBatch"),
("EXT_TIME", "timeBatch"),
("EXT_UUID", "uuidBatch"),
],
&[],
);
}
if concurrency {
crate::compare(
core,
"extended-performance/concurrency",
"extended-concurrency",
&[
include_str!("../samples.rs"),
include_str!("concurrency.rs"),
]
.concat(),
&[
("EXT_CHANNEL", "channelRoundtrip"),
("EXT_PULL", "streamPull"),
("EXT_PREFIX", "streamPrefix"),
("EXT_BOUNDARY", "streamBoundary"),
("EXT_PARALLEL", "parallelBounded"),
],
&[],
);
}
primitives || concurrency
}
@@ -0,0 +1,274 @@
use dever_runtime::time::calendar::{Date, DateTime, Time};
use dever_runtime::value::secret::Secret;
use sha2::{Digest, Sha256};
fn primitive_fault() -> Fault {
&FaultInfo {
message: "extended primitive failed",
source: "extended-primitives-reference",
line: 1,
column: 1,
}
}
fn digest_score(bytes: &dever_runtime::Bytes) -> u64 {
bytes.iter().fold(0u64, |score, byte| {
score.wrapping_mul(31).wrapping_add(u64::from(*byte))
})
}
fn sha_reference(bytes: &dever_runtime::Bytes) -> Result<dever_runtime::Bytes, Fault> {
Ok(Sha256::digest(bytes).to_vec().into())
}
struct HmacCase {
key: Secret,
bytes: dever_runtime::Bytes,
}
fn hmac_generated(values: &[HmacCase]) -> Result<dever_runtime::Bytes, Fault> {
let Some(value) = values.first() else {
return Ok(dever_runtime::Bytes::new());
};
EXT_HMAC(&value.key, &value.bytes)
}
// 共用批准的 Secret 接收点;不读取密钥内部字节。
fn hmac_reference(values: &[HmacCase]) -> Result<dever_runtime::Bytes, Fault> {
Ok(values
.first()
.map_or_else(Vec::new, |value| {
dever_runtime::crypto::hmac_sha256(&value.key, &value.bytes)
})
.into())
}
fn datetime_generated(values: &[String]) -> Result<Vec<String>, Fault> {
EXT_DATETIME(values).map_err(|_| primitive_fault())
}
fn datetime_reference(values: &[String]) -> Result<Vec<String>, Fault> {
values
.iter()
.map(|value| {
DateTime::parse(value)
.and_then(DateTime::format)
.map_err(|_| primitive_fault())
})
.collect()
}
fn date_generated(values: &[String]) -> Result<Vec<String>, Fault> {
EXT_DATE(values).map_err(|_| primitive_fault())
}
fn date_reference(values: &[String]) -> Result<Vec<String>, Fault> {
values
.iter()
.map(|value| {
Date::parse(value)
.and_then(Date::format)
.map_err(|_| primitive_fault())
})
.collect()
}
fn time_generated(values: &[String]) -> Result<Vec<String>, Fault> {
EXT_TIME(values).map_err(|_| primitive_fault())
}
fn time_reference(values: &[String]) -> Result<Vec<String>, Fault> {
values
.iter()
.map(|value| {
Time::parse(value)
.and_then(Time::format)
.map_err(|_| primitive_fault())
})
.collect()
}
fn text_score(values: &Vec<String>) -> u64 {
values
.iter()
.flat_map(|value| value.bytes())
.fold(0u64, |score, byte| {
score.wrapping_mul(31).wrapping_add(u64::from(byte))
})
}
fn uuid_generated(values: &[String]) -> Result<Vec<Option<String>>, Fault> {
EXT_UUID(values)
}
fn uuid_reference(values: &[String]) -> Result<Vec<Option<String>>, Fault> {
Ok(values
.iter()
.map(|value| {
if value.len() != 36 {
return None;
}
uuid::Uuid::try_parse(value)
.ok()
.map(|value| value.hyphenated().to_string())
})
.collect())
}
fn uuid_score(values: &Vec<Option<String>>) -> u64 {
values.iter().fold(0u64, |score, value| {
value.as_ref().map_or(score.wrapping_add(1), |value| {
value.bytes().fold(score.wrapping_add(2), |score, byte| {
score.wrapping_mul(31).wrapping_add(u64::from(byte))
})
})
})
}
fn check_primitives() {
assert_eq!(
EXT_SHA256(&dever_runtime::Bytes::from_static(b"abc"))
.unwrap()
.as_ref(),
[
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
0xf2, 0x00, 0x15, 0xad,
]
);
// 沿用已有密码学验收的公开向量,不使用真实凭据。
let vector = [HmacCase {
key: Secret::from_input(vec![0x0b; 20]),
bytes: dever_runtime::Bytes::from_static(b"Hi There"),
}];
assert_eq!(
hmac_generated(&vector).unwrap().as_ref(),
[
0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b,
0xf1, 0x2b, 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, 0x26, 0xe9, 0x37, 0x6c,
0x2e, 0x32, 0xcf, 0xf7,
]
);
assert_eq!(
hmac_generated(&vector).unwrap(),
hmac_reference(&vector).unwrap()
);
assert_eq!(
datetime_generated(&["2024-02-29T12:34:56.12+08:00".into()]).unwrap(),
["2024-02-29T04:34:56.120Z"]
);
assert_eq!(
time_generated(&["12:34:56.000".into()]).unwrap(),
["12:34:56"]
);
for value in ["2023-02-29", "2024-2-29"] {
let values = [value.to_owned()];
assert!(date_generated(&values).is_err());
assert!(date_reference(&values).is_err());
}
for value in ["24:00:00", "12:34:56.1"] {
let values = [value.to_owned()];
assert!(time_generated(&values).is_err());
assert!(time_reference(&values).is_err());
}
let values = ["2024-02-29T00:00:00.1234Z".to_owned()];
assert!(datetime_generated(&values).is_err());
assert!(datetime_reference(&values).is_err());
}
fn main() {
check_primitives();
println!("case,sample,implementation,elapsed_ns,checksum");
for size in [0usize, 64, 4096] {
let bytes = dever_runtime::Bytes::from(vec![0x61; size]);
compare_bytes(
&format!("crypto_sha256_{size}"),
&bytes,
2000,
EXT_SHA256,
sha_reference,
digest_score,
);
let values = [HmacCase {
key: Secret::from_input(vec![0x0b; 20]),
bytes,
}];
compare_named(
&format!("crypto_hmac_{size}_shared_runtime"),
&values,
2000,
hmac_generated,
hmac_reference,
digest_score,
"rust_runtime",
);
}
// 日历参照保留相同精度、年份范围、非法输入和 UTC 规范化规则。
let datetimes = [
"1970-01-01T00:00:00Z",
"2024-02-29T12:34:56.12+08:00",
"1969-12-31T23:59:59.999Z",
]
.map(str::to_owned);
let dates = ["2024-02-29", "2000-01-01", "9999-12-31"].map(str::to_owned);
let times = ["00:00:00", "12:34:56.000", "23:59:59.999"].map(str::to_owned);
compare_named(
"calendar_datetime_shared_runtime",
&datetimes,
2000,
datetime_generated,
datetime_reference,
text_score,
"rust_runtime",
);
compare_named(
"calendar_date_shared_runtime",
&dates,
2000,
date_generated,
date_reference,
text_score,
"rust_runtime",
);
compare_named(
"calendar_time_shared_runtime",
&times,
2000,
time_generated,
time_reference,
text_score,
"rust_runtime",
);
let valid = [
"550E8400-E29B-41D4-A716-446655440000",
"00000000-0000-0000-0000-000000000000",
]
.map(str::to_owned);
assert_eq!(
uuid_generated(&valid).unwrap()[0].as_deref(),
Some("550e8400-e29b-41d4-a716-446655440000")
);
let invalid = [
"",
"550e8400e29b41d4a716446655440000",
"00000000-0000-0000-0000-00000000000-",
]
.map(str::to_owned);
assert_eq!(uuid_generated(&invalid).unwrap(), vec![None; invalid.len()]);
compare(
"uuid_parse_format",
&valid,
2000,
uuid_generated,
uuid_reference,
uuid_score,
);
compare(
"uuid_parse_invalid",
&invalid,
2000,
uuid_generated,
uuid_reference,
uuid_score,
);
}