Skip to content

Commit 7d0111e

Browse files
committed
Add simplified arena allocator test
1 parent 9c4c495 commit 7d0111e

File tree

3 files changed

+138
-12
lines changed

3 files changed

+138
-12
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent};
2+
use cgp::extra::handler::CanTryCompute;
3+
use cgp::prelude::*;
4+
use cgp_error_anyhow::{RaiseAnyhowError, UseAnyhowError};
5+
use cgp_serde::components::{CanDeserializeValue, ValueDeserializer, ValueDeserializerComponent};
6+
use cgp_serde::providers::{DeserializeExtend, DeserializeRecordFields, UseSerde};
7+
use cgp_serde_json::code::{DeserializeJson, SerializeJson};
8+
use cgp_serde_json::{DeserializeFromJsonString, SerializeToJsonString};
9+
use typed_arena::Arena;
10+
11+
#[cgp_auto_getter]
12+
pub trait HasArena<'a, T: 'a> {
13+
fn arena(&self) -> &&'a Arena<T>;
14+
}
15+
16+
#[cgp_impl(new DeserializeAndAllocate)]
17+
impl<'de, 'a, Context, Value> ValueDeserializer<'de, &'a Value> for Context
18+
where
19+
Context: HasArena<'a, Value> + CanDeserializeValue<'de, Value>,
20+
{
21+
fn deserialize<D>(context: &Context, deserializer: D) -> Result<&'a Value, D::Error>
22+
where
23+
D: serde::Deserializer<'de>,
24+
{
25+
let value = context.deserialize(deserializer)?;
26+
let value = context.arena().alloc(value);
27+
28+
Ok(value)
29+
}
30+
}
31+
32+
#[derive(Debug, PartialEq, Eq, HasFields, BuildField)]
33+
pub struct Coord {
34+
pub x: u64,
35+
pub y: u64,
36+
pub z: u64,
37+
}
38+
39+
#[derive(Debug, PartialEq, Eq, HasFields, BuildField)]
40+
pub struct Payload<'a> {
41+
pub id: u64,
42+
pub coords: Vec<&'a Coord>,
43+
}
44+
45+
#[derive(HasField)]
46+
pub struct App<'a> {
47+
pub arena: &'a Arena<Coord>,
48+
}
49+
50+
delegate_components! {
51+
<'a> App<'a> {
52+
ErrorTypeProviderComponent:
53+
UseAnyhowError,
54+
ErrorRaiserComponent:
55+
RaiseAnyhowError,
56+
ValueDeserializerComponent:
57+
UseDelegate<new DeserializeComponents {
58+
u64: UseSerde,
59+
Coord:
60+
DeserializeRecordFields,
61+
<'a> &'a Coord:
62+
DeserializeAndAllocate,
63+
<'a> Vec<&'a Coord>:
64+
DeserializeExtend,
65+
<'a> Payload<'a>:
66+
DeserializeRecordFields,
67+
68+
}>,
69+
TryComputerComponent:
70+
UseDelegate<new JsonEncodingComponents {
71+
SerializeJson:
72+
SerializeToJsonString,
73+
<T> DeserializeJson<T>:
74+
DeserializeFromJsonString
75+
}>,
76+
}
77+
}
78+
79+
check_components! {
80+
<'a> CanUseApp for App<'a> {
81+
ValueDeserializerComponent:
82+
(Life<'a>, Coord),
83+
84+
}
85+
}
86+
87+
check_components! {
88+
<'de, 'a> CanDeserializeApp for App<'a> {
89+
ValueDeserializerComponent: [
90+
(Life<'de>, u64),
91+
(Life<'de>, Coord),
92+
(Life<'de>, &'a Coord),
93+
(Life<'de>, Payload<'a>),
94+
]
95+
}
96+
}
97+
98+
#[test]
99+
fn test_deserialize_with_arena() {
100+
let serialized = r#"
101+
{
102+
"id": 8,
103+
"coords": [
104+
{ "x": 1, "y": 2, "z": 3 },
105+
{ "x": 4, "y": 5, "z": 6 }
106+
]
107+
}
108+
"#;
109+
110+
let arena = Arena::new();
111+
let app = App { arena: &arena };
112+
113+
let deserialized: Payload<'_> = app
114+
.try_compute(PhantomData::<DeserializeJson<Payload<'_>>>, &serialized)
115+
.unwrap();
116+
assert_eq!(
117+
deserialized,
118+
Payload {
119+
id: 8,
120+
coords: vec![&Coord { x: 1, y: 2, z: 3 }, &Coord { x: 4, y: 5, z: 6 },]
121+
}
122+
);
123+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod arena;
2+
pub mod arena_simplified;
23
pub mod basic;
34
pub mod nested;

crates/cgp-serde-tests/src/tests/nested.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ use cgp_serde_extra::providers::{
77
};
88
use chrono::{DateTime, TimeZone, Utc};
99

10-
#[derive(HasField, HasFields)]
10+
#[derive(CgpData)]
1111
pub struct EncryptedMessage {
1212
pub message_id: u64,
1313
pub author_id: u64,
1414
pub date: DateTime<Utc>,
1515
pub encrypted_data: Vec<u8>,
1616
}
1717

18-
#[derive(HasField, HasFields)]
18+
#[derive(CgpData)]
1919
pub struct MessagesByTopic {
2020
pub encrypted_topic: Vec<u8>,
2121
pub messages: Vec<EncryptedMessage>,
2222
}
2323

24-
#[derive(HasField, HasFields)]
24+
#[derive(CgpData)]
2525
pub struct MessagesArchive {
2626
pub decryption_key: Vec<u8>,
2727
pub messages_by_topics: Vec<MessagesByTopic>,
@@ -125,27 +125,29 @@ fn test_nested_serialization() {
125125
let archive = MessagesArchive {
126126
decryption_key: b"top-secret".into(),
127127
messages_by_topics: vec![MessagesByTopic {
128-
encrypted_topic: b"secret-deals".into(),
128+
encrypted_topic: b"All about CGP".into(),
129129
messages: vec![
130130
EncryptedMessage {
131131
message_id: 1,
132-
author_id: 1,
133-
date: Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(),
134-
encrypted_data: b"buy 1 free 1".into(),
132+
author_id: 2,
133+
date: Utc.with_ymd_and_hms(2025, 11, 3, 14, 15, 0).unwrap(),
134+
encrypted_data: b"Hello from RustLab!".into(),
135135
},
136136
EncryptedMessage {
137-
message_id: 2,
137+
message_id: 4,
138138
author_id: 8,
139-
date: Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap(),
140-
encrypted_data: b"sales start tomorrow".into(),
139+
date: Utc.with_ymd_and_hms(2025, 12, 19, 23, 45, 0).unwrap(),
140+
encrypted_data: b"One year anniversary!".into(),
141141
},
142142
],
143143
}],
144144
};
145145

146-
let serialized = serde_json::to_string(&SerializeWithContext::new(&AppA, &archive)).unwrap();
146+
let serialized =
147+
serde_json::to_string_pretty(&SerializeWithContext::new(&AppA, &archive)).unwrap();
147148
println!("serialized with A: {serialized}");
148149

149-
let serialized = serde_json::to_string(&SerializeWithContext::new(&AppB, &archive)).unwrap();
150+
let serialized =
151+
serde_json::to_string_pretty(&SerializeWithContext::new(&AppB, &archive)).unwrap();
150152
println!("serialized with B: {serialized}");
151153
}

0 commit comments

Comments
 (0)