1use crate::introspect::{self, TypeVariant};
4use crate::schema_capnp::value;
5use crate::Result;
6use crate::{dynamic_list, dynamic_struct};
7
8#[derive(Clone, Copy)]
10pub enum Reader<'a> {
11 Void,
12 Bool(bool),
13 Int8(i8),
14 Int16(i16),
15 Int32(i32),
16 Int64(i64),
17 UInt8(u8),
18 UInt16(u16),
19 UInt32(u32),
20 UInt64(u64),
21 Float32(f32),
22 Float64(f64),
23 Enum(Enum),
24 Text(crate::text::Reader<'a>),
25 Data(crate::data::Reader<'a>),
26 Struct(dynamic_struct::Reader<'a>),
27 List(dynamic_list::Reader<'a>),
28 AnyPointer(crate::any_pointer::Reader<'a>),
29 Capability(Capability),
30}
31
32impl<'a> Reader<'a> {
33 pub fn new(value: value::Reader<'a>, ty: introspect::Type) -> Result<Self> {
34 match (value.which()?, ty.which()) {
35 (value::Void(()), _) => Ok(Reader::Void),
36 (value::Bool(b), _) => Ok(Reader::Bool(b)),
37 (value::Int8(x), _) => Ok(Reader::Int8(x)),
38 (value::Int16(x), _) => Ok(Reader::Int16(x)),
39 (value::Int32(x), _) => Ok(Reader::Int32(x)),
40 (value::Int64(x), _) => Ok(Reader::Int64(x)),
41 (value::Uint8(x), _) => Ok(Reader::UInt8(x)),
42 (value::Uint16(x), _) => Ok(Reader::UInt16(x)),
43 (value::Uint32(x), _) => Ok(Reader::UInt32(x)),
44 (value::Uint64(x), _) => Ok(Reader::UInt64(x)),
45 (value::Float32(x), _) => Ok(Reader::Float32(x)),
46 (value::Float64(x), _) => Ok(Reader::Float64(x)),
47 (value::Enum(d), TypeVariant::Enum(e)) => Ok(Reader::Enum(Enum::new(d, e.into()))),
48 (value::Text(t), _) => Ok(Reader::Text(t?)),
49 (value::Data(d), _) => Ok(Reader::Data(d?)),
50 (value::Struct(d), TypeVariant::Struct(schema)) => Ok(Reader::Struct(
51 dynamic_struct::Reader::new(d.reader.get_struct(None)?, schema.into()),
52 )),
53 (value::List(l), TypeVariant::List(element_type)) => {
54 Ok(Reader::List(dynamic_list::Reader::new(
55 l.reader
56 .get_list(element_type.expected_element_size(), None)?,
57 element_type,
58 )))
59 }
60 (value::Interface(()), TypeVariant::Capability) => Ok(Capability.into()),
61 (value::AnyPointer(a), TypeVariant::AnyPointer) => Ok(a.into()),
62 _ => Err(crate::Error::from_kind(crate::ErrorKind::TypeMismatch)),
63 }
64 }
65
66 pub fn downcast<T: DowncastReader<'a>>(self) -> T {
69 T::downcast_reader(self)
70 }
71
72 pub fn downcast_struct<T: crate::traits::OwnedStruct>(self) -> T::Reader<'a> {
80 let sr: dynamic_struct::Reader = self.downcast();
81 sr.downcast::<T>()
82 }
83}
84
85impl<'a> From<()> for Reader<'a> {
86 fn from((): ()) -> Reader<'a> {
87 Reader::Void
88 }
89}
90
91macro_rules! primitive_dynamic_value(
92 ($t:ty, $v:ident) => (
93 impl <'a> From<$t> for Reader<'a> {
94 fn from(x: $t) -> Reader<'a> { Reader::$v(x) }
95 }
96 )
97);
98
99primitive_dynamic_value!(bool, Bool);
100primitive_dynamic_value!(i8, Int8);
101primitive_dynamic_value!(i16, Int16);
102primitive_dynamic_value!(i32, Int32);
103primitive_dynamic_value!(i64, Int64);
104primitive_dynamic_value!(u8, UInt8);
105primitive_dynamic_value!(u16, UInt16);
106primitive_dynamic_value!(u32, UInt32);
107primitive_dynamic_value!(u64, UInt64);
108primitive_dynamic_value!(f32, Float32);
109primitive_dynamic_value!(f64, Float64);
110
111pub trait DowncastReader<'a> {
113 fn downcast_reader(v: Reader<'a>) -> Self;
114}
115
116impl<'a> DowncastReader<'a> for () {
117 fn downcast_reader(value: Reader<'a>) {
118 let Reader::Void = value else {
119 panic!("error downcasting to void")
120 };
121 }
122}
123
124macro_rules! downcast_reader_impl(
125 ($t:ty, $v:ident, $s:expr) => (
126 impl <'a> DowncastReader<'a> for $t {
127 fn downcast_reader(value: Reader<'a>) -> Self {
128 let Reader::$v(x) = value else { panic!("error downcasting to {}", $s) };
129 x
130 }
131 }
132 )
133);
134
135downcast_reader_impl!(bool, Bool, "bool");
136downcast_reader_impl!(i8, Int8, "i8");
137downcast_reader_impl!(i16, Int16, "i16");
138downcast_reader_impl!(i32, Int32, "i32");
139downcast_reader_impl!(i64, Int64, "i64");
140downcast_reader_impl!(u8, UInt8, "u8");
141downcast_reader_impl!(u16, UInt16, "u16");
142downcast_reader_impl!(u32, UInt32, "u32");
143downcast_reader_impl!(u64, UInt64, "u64");
144downcast_reader_impl!(f32, Float32, "f32");
145downcast_reader_impl!(f64, Float64, "f64");
146downcast_reader_impl!(Enum, Enum, "enum");
147downcast_reader_impl!(crate::text::Reader<'a>, Text, "text");
148downcast_reader_impl!(crate::data::Reader<'a>, Data, "data");
149downcast_reader_impl!(dynamic_list::Reader<'a>, List, "list");
150downcast_reader_impl!(dynamic_struct::Reader<'a>, Struct, "struct");
151downcast_reader_impl!(crate::any_pointer::Reader<'a>, AnyPointer, "anypointer");
152
153pub enum Builder<'a> {
155 Void,
156 Bool(bool),
157 Int8(i8),
158 Int16(i16),
159 Int32(i32),
160 Int64(i64),
161 UInt8(u8),
162 UInt16(u16),
163 UInt32(u32),
164 UInt64(u64),
165 Float32(f32),
166 Float64(f64),
167 Enum(Enum),
168 Text(crate::text::Builder<'a>),
169 Data(crate::data::Builder<'a>),
170 Struct(dynamic_struct::Builder<'a>),
171 List(dynamic_list::Builder<'a>),
172 AnyPointer(crate::any_pointer::Builder<'a>),
173 Capability(Capability),
174}
175
176impl<'a> Builder<'a> {
177 pub fn reborrow(&mut self) -> Builder<'_> {
178 match self {
179 Builder::Void => Builder::Void,
180 Builder::Bool(b) => Builder::Bool(*b),
181 Builder::Int8(x) => Builder::Int8(*x),
182 Builder::Int16(x) => Builder::Int16(*x),
183 Builder::Int32(x) => Builder::Int32(*x),
184 Builder::Int64(x) => Builder::Int64(*x),
185 Builder::UInt8(x) => Builder::UInt8(*x),
186 Builder::UInt16(x) => Builder::UInt16(*x),
187 Builder::UInt32(x) => Builder::UInt32(*x),
188 Builder::UInt64(x) => Builder::UInt64(*x),
189 Builder::Float32(x) => Builder::Float32(*x),
190 Builder::Float64(x) => Builder::Float64(*x),
191 Builder::Enum(e) => Builder::Enum(*e),
192 Builder::Text(t) => Builder::Text(t.reborrow()),
193 Builder::Data(d) => Builder::Data(d),
194 Builder::Struct(ref mut s) => Builder::Struct(s.reborrow()),
195 Builder::List(ref mut l) => Builder::List(l.reborrow()),
196 Builder::AnyPointer(ref mut a) => Builder::AnyPointer(a.reborrow()),
197 Builder::Capability(c) => Builder::Capability(*c),
198 }
199 }
200
201 pub fn into_reader(self) -> Reader<'a> {
202 match self {
203 Builder::Void => Reader::Void,
204 Builder::Bool(b) => Reader::Bool(b),
205 Builder::Int8(x) => Reader::Int8(x),
206 Builder::Int16(x) => Reader::Int16(x),
207 Builder::Int32(x) => Reader::Int32(x),
208 Builder::Int64(x) => Reader::Int64(x),
209 Builder::UInt8(x) => Reader::UInt8(x),
210 Builder::UInt16(x) => Reader::UInt16(x),
211 Builder::UInt32(x) => Reader::UInt32(x),
212 Builder::UInt64(x) => Reader::UInt64(x),
213 Builder::Float32(x) => Reader::Float32(x),
214 Builder::Float64(x) => Reader::Float64(x),
215 Builder::Enum(e) => Reader::Enum(e),
216 Builder::Text(t) => Reader::Text(t.into_reader()),
217 Builder::Data(d) => Reader::Data(d),
218 Builder::Struct(s) => Reader::Struct(s.into_reader()),
219 Builder::List(l) => Reader::List(l.into_reader()),
220 Builder::AnyPointer(a) => Reader::AnyPointer(a.into_reader()),
221 Builder::Capability(c) => Reader::Capability(c),
222 }
223 }
224
225 pub fn downcast<T: DowncastBuilder<'a>>(self) -> T {
228 T::downcast_builder(self)
229 }
230
231 pub fn downcast_struct<T: crate::traits::OwnedStruct>(self) -> T::Builder<'a> {
239 let sb: dynamic_struct::Builder = self.downcast();
240 sb.downcast::<T>()
241 }
242}
243
244pub trait DowncastBuilder<'a> {
246 fn downcast_builder(v: Builder<'a>) -> Self;
247}
248
249impl<'a> DowncastBuilder<'a> for () {
250 fn downcast_builder(value: Builder<'a>) {
251 let Builder::Void = value else {
252 panic!("error downcasting to void")
253 };
254 }
255}
256
257macro_rules! downcast_builder_impl(
258 ($t:ty, $v:ident, $s:expr) => (
259 impl <'a> DowncastBuilder<'a> for $t {
260 fn downcast_builder(value: Builder<'a>) -> Self {
261 let Builder::$v(x) = value else { panic!("error downcasting to {}", $s) };
262 x
263 }
264 }
265 )
266);
267
268downcast_builder_impl!(bool, Bool, "bool");
269downcast_builder_impl!(i8, Int8, "i8");
270downcast_builder_impl!(i16, Int16, "i16");
271downcast_builder_impl!(i32, Int32, "i32");
272downcast_builder_impl!(i64, Int64, "i64");
273downcast_builder_impl!(u8, UInt8, "u8");
274downcast_builder_impl!(u16, UInt16, "u16");
275downcast_builder_impl!(u32, UInt32, "u32");
276downcast_builder_impl!(u64, UInt64, "u64");
277downcast_builder_impl!(f32, Float32, "f32");
278downcast_builder_impl!(f64, Float64, "f64");
279downcast_builder_impl!(Enum, Enum, "enum");
280downcast_builder_impl!(crate::text::Builder<'a>, Text, "text");
281downcast_builder_impl!(crate::data::Builder<'a>, Data, "data");
282downcast_builder_impl!(dynamic_list::Builder<'a>, List, "list");
283downcast_builder_impl!(dynamic_struct::Builder<'a>, Struct, "struct");
284downcast_builder_impl!(crate::any_pointer::Builder<'a>, AnyPointer, "anypointer");
285
286#[derive(Clone, Copy)]
288pub struct Enum {
289 value: u16,
290 schema: crate::schema::EnumSchema,
291}
292
293impl Enum {
294 pub fn new(value: u16, schema: crate::schema::EnumSchema) -> Self {
295 Self { value, schema }
296 }
297
298 pub fn get_value(&self) -> u16 {
300 self.value
301 }
302
303 pub fn get_enumerant(self) -> crate::Result<Option<crate::schema::Enumerant>> {
305 let enumerants = self.schema.get_enumerants()?;
306 if (self.value) < enumerants.len() {
307 Ok(Some(enumerants.get(self.value)))
308 } else {
309 Ok(None)
310 }
311 }
312}
313
314impl<'a> From<Enum> for Reader<'a> {
315 fn from(e: Enum) -> Reader<'a> {
316 Reader::Enum(e)
317 }
318}
319
320impl<'a> From<Enum> for Builder<'a> {
321 fn from(e: Enum) -> Builder<'a> {
322 Builder::Enum(e)
323 }
324}
325
326#[derive(Clone, Copy)]
329pub struct Capability;
330
331impl<'a> From<Capability> for Reader<'a> {
332 fn from(c: Capability) -> Reader<'a> {
333 Reader::Capability(c)
334 }
335}
336
337impl<'a> From<Capability> for Builder<'a> {
338 fn from(c: Capability) -> Builder<'a> {
339 Builder::Capability(c)
340 }
341}