icydb_core/value/
output.rs1use crate::{
2 types::{
3 Account, Date, Decimal, Duration, Float32, Float64, Principal, Subaccount, Timestamp, U256,
4 Ulid,
5 },
6 value::PublicValue,
7};
8
9use serde::{Deserialize, Deserializer};
10
11#[cfg(test)]
12use crate::value::Value;
13
14#[repr(transparent)]
19#[derive(Clone, Debug, Eq, PartialEq)]
20pub struct OutputValue(PublicValue);
21
22impl OutputValue {
23 #[must_use]
25 pub const fn as_public(&self) -> &PublicValue {
26 &self.0
27 }
28
29 #[must_use]
31 pub fn into_public(self) -> PublicValue {
32 self.0
33 }
34
35 pub(crate) const fn from_public(value: PublicValue) -> Self {
36 Self(value)
37 }
38
39 #[must_use]
41 pub const fn account(value: Account) -> Self {
42 Self(PublicValue::Account(value))
43 }
44
45 #[must_use]
47 pub const fn blob(value: Vec<u8>) -> Self {
48 Self(PublicValue::Blob(value))
49 }
50
51 #[must_use]
53 pub const fn boolean(value: bool) -> Self {
54 Self(PublicValue::Bool(value))
55 }
56
57 #[must_use]
59 pub const fn date(value: Date) -> Self {
60 Self(PublicValue::Date(value))
61 }
62
63 #[must_use]
65 pub const fn decimal(value: Decimal) -> Self {
66 Self(PublicValue::Decimal(value))
67 }
68
69 #[must_use]
71 pub const fn duration(value: Duration) -> Self {
72 Self(PublicValue::Duration(value))
73 }
74
75 #[must_use]
77 pub const fn float32(value: Float32) -> Self {
78 Self(PublicValue::Float32(value))
79 }
80
81 #[must_use]
83 pub const fn float64(value: Float64) -> Self {
84 Self(PublicValue::Float64(value))
85 }
86
87 #[must_use]
89 pub const fn int64(value: i64) -> Self {
90 Self(PublicValue::Int64(value))
91 }
92
93 #[must_use]
95 pub const fn int128(value: i128) -> Self {
96 Self(PublicValue::Int128(value))
97 }
98
99 #[must_use]
101 pub const fn list(values: Vec<PublicValue>) -> Self {
102 Self(PublicValue::List(values))
103 }
104
105 #[must_use]
107 pub const fn map(entries: Vec<(PublicValue, PublicValue)>) -> Self {
108 Self(PublicValue::Map(entries))
109 }
110
111 #[must_use]
113 pub const fn null() -> Self {
114 Self(PublicValue::Null)
115 }
116
117 #[must_use]
119 pub const fn principal(value: Principal) -> Self {
120 Self(PublicValue::Principal(value))
121 }
122
123 #[must_use]
125 pub const fn subaccount(value: Subaccount) -> Self {
126 Self(PublicValue::Subaccount(value))
127 }
128
129 #[must_use]
131 pub const fn text(value: String) -> Self {
132 Self(PublicValue::Text(value))
133 }
134
135 #[must_use]
137 pub const fn timestamp(value: Timestamp) -> Self {
138 Self(PublicValue::Timestamp(value))
139 }
140
141 #[must_use]
143 pub const fn nat64(value: u64) -> Self {
144 Self(PublicValue::Nat64(value))
145 }
146
147 #[must_use]
149 pub const fn nat128(value: u128) -> Self {
150 Self(PublicValue::Nat128(value))
151 }
152
153 #[must_use]
155 pub const fn ulid(value: Ulid) -> Self {
156 Self(PublicValue::Ulid(value))
157 }
158
159 #[must_use]
161 pub const fn unit() -> Self {
162 Self(PublicValue::Unit)
163 }
164
165 #[must_use]
167 pub const fn u256(value: U256) -> Self {
168 Self(PublicValue::U256(value))
169 }
170}
171
172impl<'de> Deserialize<'de> for OutputValue {
173 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
174 where
175 D: Deserializer<'de>,
176 {
177 PublicValue::deserialize(deserializer).map(Self)
178 }
179}
180
181#[cfg(test)]
182impl From<Value> for OutputValue {
183 fn from(value: Value) -> Self {
184 Self(
185 PublicValue::try_from_runtime_non_enum(&value)
186 .expect("test output conversion requires accepted enum catalog"),
187 )
188 }
189}
190
191#[must_use]
193pub fn render_output_value_text(value: &OutputValue) -> String {
194 value.as_public().render_text()
195}
196
197impl serde::Serialize for OutputValue {
198 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
199 serde::Serialize::serialize(&self.0, serializer)
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use crate::value::{OutputValue, PublicValue, Value};
206
207 #[test]
208 fn output_value_from_runtime_value_keeps_recursive_collection_shape() {
209 let runtime = Value::List(vec![
210 Value::Nat64(7),
211 Value::Map(vec![(Value::Text("x".to_string()), Value::Bool(true))]),
212 ]);
213
214 assert_eq!(
215 OutputValue::from(runtime),
216 OutputValue::list(vec![
217 PublicValue::Nat64(7),
218 PublicValue::Map(vec![(
219 PublicValue::Text("x".to_string()),
220 PublicValue::Bool(true),
221 )]),
222 ]),
223 );
224 }
225}