1use serde::de::{Deserialize as DeserializeIface, Deserializer};
6use serde_derive::Deserialize;
7use std::collections::HashMap;
8
9use std::sync::{Arc, Weak};
10
11use crate::error::{Error, Result};
12use crate::value::Value;
13
14trait Named {
17 fn name(&self) -> String;
18}
19
20impl<T: Named> Named for Arc<T> {
21 fn name(&self) -> String {
22 Arc::as_ref(self).name()
23 }
24}
25
26macro_rules! named {
27 ($ident:ty) => {
28 impl Named for $ident {
29 fn name(&self) -> String {
30 self.name.clone()
31 }
32 }
33 };
34}
35
36fn object_type<'de, D: Deserializer<'de>>(
38 deserializer: D,
39) -> std::result::Result<Option<fidl::ObjectType>, D::Error> {
40 Ok(Option::<u32>::deserialize(deserializer)?.map(|x| fidl::ObjectType::from_raw(x)))
41}
42
43fn composed_protocols<'de, D: Deserializer<'de>>(
45 deserializer: D,
46) -> std::result::Result<Vec<String>, D::Error> {
47 #[derive(Deserialize)]
48 struct ComposedProtocol {
49 name: String,
50 }
51 Ok(Vec::<ComposedProtocol>::deserialize(deserializer)?.into_iter().map(|x| x.name).collect())
52}
53
54fn rights<'de, D: Deserializer<'de>>(
56 deserializer: D,
57) -> std::result::Result<Option<fidl::Rights>, D::Error> {
58 if let Some(rights) = Option::<u32>::deserialize(deserializer)? {
59 Ok(Some(fidl::Rights::from_bits_truncate(rights)))
60 } else {
61 Ok(None)
62 }
63}
64
65fn hash_by_name<'de, D: Deserializer<'de>, T: Named + DeserializeIface<'de>>(
67 deserializer: D,
68) -> std::result::Result<HashMap<String, T>, D::Error> {
69 let mut ret = HashMap::new();
70 for item in Vec::<T>::deserialize(deserializer)? {
71 ret.insert(item.name().clone(), item);
72 }
73 Ok(ret)
74}
75
76fn hash_by_name_arc<'de, D: Deserializer<'de>, T: Named + DeserializeIface<'de>>(
78 deserializer: D,
79) -> std::result::Result<HashMap<String, Arc<T>>, D::Error> {
80 let mut ret = HashMap::new();
81 for item in Vec::<T>::deserialize(deserializer)? {
82 ret.insert(item.name().clone(), Arc::new(item));
83 }
84 Ok(ret)
85}
86
87fn hash_by_ordinal<'de, D: Deserializer<'de>>(
90 deserializer: D,
91) -> std::result::Result<HashMap<u64, TableOrUnionMember>, D::Error> {
92 let mut ret = HashMap::new();
93 for item in Vec::<TableOrUnionMember>::deserialize(deserializer)? {
94 ret.insert(item.ordinal, item);
95 }
96 Ok(ret)
97}
98
99fn extract_struct_size<'de, D: Deserializer<'de>>(
101 deserializer: D,
102) -> std::result::Result<usize, D::Error> {
103 Ok(TypeShape::deserialize(deserializer)?.inline_size)
104}
105
106fn extract_member_offset<'de, D: Deserializer<'de>>(
108 deserializer: D,
109) -> std::result::Result<usize, D::Error> {
110 Ok(MemberShape::deserialize(deserializer)?.offset)
111}
112
113#[derive(Deserialize)]
114struct Module {
115 name: String,
116 #[serde(deserialize_with = "hash_by_name")]
117 bits_declarations: HashMap<String, Bits>,
118 #[serde(deserialize_with = "hash_by_name")]
119 enum_declarations: HashMap<String, Enum>,
120 #[serde(deserialize_with = "hash_by_name")]
121 protocol_declarations: HashMap<String, Protocol>,
122 #[serde(deserialize_with = "hash_by_name")]
123 table_declarations: HashMap<String, TableOrUnion>,
124 #[serde(deserialize_with = "hash_by_name")]
125 struct_declarations: HashMap<String, Struct>,
126 #[serde(deserialize_with = "hash_by_name")]
127 union_declarations: HashMap<String, TableOrUnion>,
128 declarations: HashMap<String, String>,
129}
130
131#[derive(Deserialize)]
132pub struct TableOrUnion {
133 pub name: String,
134 pub strict: bool,
135 #[serde(deserialize_with = "hash_by_ordinal")]
136 pub members: HashMap<u64, TableOrUnionMember>,
137}
138named!(TableOrUnion);
139
140#[derive(Deserialize)]
141pub struct TableOrUnionMember {
142 pub name: String,
143 #[serde(rename = "type")]
144 pub ty: Type,
145 pub ordinal: u64,
146}
147
148#[derive(Deserialize)]
149#[serde(try_from = "EnumExpanded")]
150pub struct Enum {
151 pub name: String,
152 pub ty: Type,
153 pub strict: bool,
154 pub members: Vec<ValueMember>,
155}
156named!(Enum);
157
158#[derive(Deserialize)]
159#[serde(try_from = "BitsExpanded")]
160pub struct Bits {
161 pub name: String,
162 pub ty: Type,
163 pub strict: bool,
164 pub mask: u64,
165 pub members: Vec<ValueMember>,
166}
167named!(Bits);
168
169pub struct ValueMember {
170 pub name: String,
171 pub value: Value,
172}
173
174#[derive(Deserialize)]
175struct EnumExpanded {
176 name: String,
177 #[serde(rename = "type")]
178 ty: String,
179 strict: bool,
180 members: Vec<ValueMemberExpanded>,
181}
182
183#[derive(Deserialize)]
184struct BitsExpanded {
185 name: String,
186 #[serde(rename = "type")]
187 ty: Type,
188 strict: bool,
189 members: Vec<ValueMemberExpanded>,
190 mask: String,
191}
192
193#[derive(Deserialize)]
195struct ValueMemberExpanded {
196 name: String,
197 value: ValueBlock,
198}
199
200#[derive(Deserialize)]
201struct ValueBlock {
202 value: String,
203}
204
205#[derive(Debug)]
206enum ValueConvertError {
210 FloatError { _error: std::num::ParseFloatError },
211 IntError { _error: std::num::ParseIntError },
212 BadPrimitive { _error: String },
213}
214
215impl From<std::num::ParseFloatError> for ValueConvertError {
216 fn from(item: std::num::ParseFloatError) -> ValueConvertError {
217 ValueConvertError::FloatError { _error: item }
218 }
219}
220
221impl From<std::num::ParseIntError> for ValueConvertError {
222 fn from(item: std::num::ParseIntError) -> ValueConvertError {
223 ValueConvertError::IntError { _error: item }
224 }
225}
226
227impl std::fmt::Display for ValueConvertError {
228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229 std::fmt::Debug::fmt(self, f)
230 }
231}
232
233fn convert_expanded_value_member(
234 ty: &Type,
235 container: &str,
236 members: Vec<ValueMemberExpanded>,
237) -> std::result::Result<Vec<ValueMember>, ValueConvertError> {
238 type ConverterType = dyn Fn(String) -> std::result::Result<Value, ValueConvertError>;
239
240 let converter = match ty {
241 Type::U8 => (&|x: String| Ok(Value::U8(x.parse::<u8>()?))) as &ConverterType,
242 Type::U16 => (&|x: String| Ok(Value::U16(x.parse::<u16>()?))) as &ConverterType,
243 Type::U32 => (&|x: String| Ok(Value::U32(x.parse::<u32>()?))) as &ConverterType,
244 Type::U64 => (&|x: String| Ok(Value::U64(x.parse::<u64>()?))) as &ConverterType,
245 Type::I8 => (&|x: String| Ok(Value::I8(x.parse::<i8>()?))) as &ConverterType,
246 Type::I16 => (&|x: String| Ok(Value::I16(x.parse::<i16>()?))) as &ConverterType,
247 Type::I32 => (&|x: String| Ok(Value::I32(x.parse::<i32>()?))) as &ConverterType,
248 Type::I64 => (&|x: String| Ok(Value::I64(x.parse::<i64>()?))) as &ConverterType,
249 Type::F32 => (&|x: String| Ok(Value::F32(x.parse::<f32>()?))) as &ConverterType,
250 Type::F64 => (&|x: String| Ok(Value::F64(x.parse::<f64>()?))) as &ConverterType,
251 _ => return Err(ValueConvertError::BadPrimitive { _error: container.to_owned() }),
252 };
253
254 let mut result = Vec::new();
255
256 for member in members {
257 result.push(ValueMember { name: member.name, value: converter(member.value.value)? });
258 }
259
260 Ok(result)
261}
262
263impl TryFrom<EnumExpanded> for Enum {
264 type Error = ValueConvertError;
265
266 fn try_from(exp: EnumExpanded) -> std::result::Result<Enum, Self::Error> {
267 let (name, ty, strict, members) = (exp.name, exp.ty.into(), exp.strict, exp.members);
268 let members = convert_expanded_value_member(&ty, &name, members)?;
269 Ok(Enum { name, ty, strict, members })
270 }
271}
272
273impl TryFrom<BitsExpanded> for Bits {
274 type Error = ValueConvertError;
275
276 fn try_from(exp: BitsExpanded) -> std::result::Result<Bits, Self::Error> {
277 let (name, ty, strict, members, mask) =
278 (exp.name, exp.ty, exp.strict, exp.members, exp.mask);
279 let members = convert_expanded_value_member(&ty, &name, members)?;
280 let mask = mask.parse::<u64>()?;
281 Ok(Bits { name, ty, strict, members, mask })
282 }
283}
284
285#[derive(Deserialize)]
286pub struct Protocol {
287 pub name: String,
288 #[serde(deserialize_with = "hash_by_name_arc")]
289 pub methods: HashMap<String, Arc<Method>>,
290 #[serde(deserialize_with = "composed_protocols")]
291 pub composed_protocols: Vec<String>,
292}
293named!(Protocol);
294
295#[derive(Debug, Clone, Deserialize)]
296pub struct Struct {
297 pub name: String,
298 pub members: Vec<Member>,
299 #[serde(rename = "type_shape_v2", deserialize_with = "extract_struct_size")]
300 pub size: usize,
301}
302named!(Struct);
303
304#[derive(Debug, Clone, Deserialize)]
305pub struct Member {
306 pub name: String,
307 #[serde(rename = "type")]
308 pub ty: Type,
309 #[serde(rename = "field_shape_v2", deserialize_with = "extract_member_offset")]
310 pub offset: usize,
311}
312named!(Member);
313
314#[derive(Deserialize)]
315struct MemberShape {
316 offset: usize,
317}
318
319#[derive(Deserialize)]
320struct TypeShape {
321 inline_size: usize,
322}
323
324#[derive(Debug, Deserialize)]
325pub struct Method {
326 pub name: String,
327 pub ordinal: u64,
328 pub strict: bool,
329 pub has_request: bool,
330 #[serde(rename = "maybe_request_payload")]
331 pub request: Option<Type>,
332 pub has_response: bool,
333 #[serde(rename = "maybe_response_payload")]
334 pub response: Option<Type>,
335}
336named!(Method);
337
338#[derive(Clone, Deserialize, Debug)]
339#[serde(from = "TypeInfo")]
340pub enum Type {
341 Unknown(TypeInfo),
342 UnknownString(String),
343 FrameworkError,
344 Identifier { name: String, nullable: bool },
345 Bool,
346 U8,
347 U16,
348 U32,
349 U64,
350 I8,
351 I16,
352 I32,
353 I64,
354 F32,
355 F64,
356 Array(Box<Type>, usize),
357 Vector { ty: Box<Type>, nullable: bool, element_count: Option<usize> },
358 String { nullable: bool, byte_count: Option<usize> },
359 Handle { object_type: fidl::ObjectType, rights: fidl::Rights, nullable: bool },
360 Endpoint { role: EndpointRole, protocol: String, rights: fidl::Rights, nullable: bool },
361}
362
363impl Type {
364 pub fn inline_size(&self, ns: &Namespace) -> Result<usize> {
365 use Type::*;
366
367 match self {
368 Bool | U8 | I8 => Ok(1),
369 U16 | I16 => Ok(2),
370 FrameworkError | U32 | I32 | F32 | Handle { .. } | Endpoint { .. } => Ok(4),
371 U64 | I64 | F64 => Ok(8),
372 Vector { .. } | String { .. } => Ok(16),
373 Array(a, b) => Ok(a.inline_size(ns)? * b),
374 Identifier { name, nullable } => match ns.lookup(name)? {
375 LookupResult::Bits(b) => b.ty.inline_size(ns),
376 LookupResult::Enum(e) => e.ty.inline_size(ns),
377 LookupResult::Struct(s) => Ok(if *nullable { 8 } else { s.size }),
378 LookupResult::Table(_) => Ok(16),
379 LookupResult::Union(_) => Ok(16),
380 LookupResult::Protocol(_) => Err(Error::LibraryError(format!(
381 "Protocol names cannot be used as identifiers: {}",
382 name
383 ))),
384 },
385 Unknown(_) | UnknownString(_) => {
386 Err(Error::LibraryError("Cannot get size for unknown type.".to_owned()))
387 }
388 }
389 }
390
391 pub fn is_resolved(&self, ns: &Namespace) -> bool {
392 match self {
393 Type::Unknown(_) | Type::UnknownString(_) => false,
394 Type::Identifier { name, .. } => ns.lookup(name).is_ok(),
395 _ => true,
396 }
397 }
398}
399
400#[derive(Clone, Deserialize, Debug)]
401pub struct TypeInfo {
402 #[serde(rename = "kind_v2")]
403 pub kind: TypeKind,
404 #[serde(default)]
405 #[serde(rename = "obj_type")]
406 #[serde(deserialize_with = "object_type")]
407 pub object_type: Option<fidl::ObjectType>,
408 #[serde(default)]
409 #[serde(deserialize_with = "rights")]
410 pub rights: Option<fidl::Rights>,
411 pub identifier: Option<String>,
412 pub protocol: Option<String>,
413 pub role: Option<EndpointRole>,
414 pub subtype: Option<String>,
415 pub element_type: Box<Option<TypeInfo>>,
416 pub element_count: Option<usize>,
417 pub maybe_element_count: Option<usize>,
418 #[serde(default)]
419 pub nullable: bool,
420}
421
422#[derive(Clone, Deserialize, Debug)]
423#[serde(rename_all = "lowercase")]
424pub enum TypeKind {
425 Primitive,
426 Vector,
427 Array,
428 Handle,
429 Identifier,
430 String,
431 Endpoint,
432 Internal,
433
434 #[serde(untagged)]
435 Unknown(String),
436}
437
438#[derive(Clone, Deserialize, Debug)]
439#[serde(rename_all = "lowercase")]
440pub enum EndpointRole {
441 Client,
442 Server,
443}
444
445impl From<TypeInfo> for Type {
446 fn from(info: TypeInfo) -> Type {
447 let nullable = info.nullable;
448
449 match info.kind {
450 TypeKind::Primitive => {
451 let subtype = if let Some(x) = info.subtype.clone() {
452 x
453 } else {
454 return Type::Unknown(info);
455 };
456 match subtype.into() {
457 Type::UnknownString(_) => Type::Unknown(info),
458 ty @ _ => ty,
459 }
460 }
461 TypeKind::Vector => match *info.element_type {
462 Some(t) => Type::Vector {
463 ty: Box::new(t.into()),
464 nullable,
465 element_count: info.maybe_element_count,
466 },
467 _ => Type::Unknown(info),
468 },
469 TypeKind::Array => {
470 if info.element_type.is_some() && info.element_count.is_some() {
471 Type::Array(
472 Box::new(info.element_type.unwrap().into()),
473 info.element_count.unwrap(),
474 )
475 } else {
476 Type::Unknown(info)
477 }
478 }
479 TypeKind::Handle => {
480 if let Some(object_type) = info.object_type {
481 Type::Handle {
482 object_type,
483 rights: info.rights.unwrap_or(fidl::Rights::SAME_RIGHTS),
484 nullable,
485 }
486 } else {
487 Type::Unknown(info)
488 }
489 }
490 TypeKind::Identifier => {
491 if let Some(identifier) = info.identifier {
492 Type::Identifier { name: identifier, nullable }
493 } else {
494 Type::Unknown(info)
495 }
496 }
497 TypeKind::String => Type::String { nullable, byte_count: info.maybe_element_count },
498 TypeKind::Endpoint => {
499 let Some(role) = info.role.clone() else { return Type::Unknown(info) };
500 let Some(protocol) = info.protocol.clone() else { return Type::Unknown(info) };
501 Type::Endpoint {
502 role,
503 protocol,
504 rights: info.rights.unwrap_or(fidl::Rights::CHANNEL_DEFAULT),
505 nullable: info.nullable,
506 }
507 }
508 TypeKind::Internal => {
509 if info.subtype.as_deref() == Some("framework_error") {
510 Type::FrameworkError
511 } else {
512 Type::Unknown(info)
513 }
514 }
515 TypeKind::Unknown(_) => Type::Unknown(info),
516 }
517 }
518}
519
520impl From<&str> for Type {
521 fn from(name: &str) -> Type {
522 match name.as_ref() {
523 "bool" => Type::Bool,
524 "uint8" => Type::U8,
525 "uint16" => Type::U16,
526 "uint32" => Type::U32,
527 "uint64" => Type::U64,
528 "int8" => Type::I8,
529 "int16" => Type::I16,
530 "int32" => Type::I32,
531 "int64" => Type::I64,
532 "float32" => Type::F32,
533 "float64" => Type::F64,
534 _ => Type::UnknownString(name.to_owned()),
535 }
536 }
537}
538
539impl From<String> for Type {
540 fn from(name: String) -> Type {
541 name.as_str().into()
542 }
543}
544
545pub enum LookupResult<'a> {
546 Bits(&'a Bits),
547 Enum(&'a Enum),
548 Protocol(&'a Protocol),
549 Struct(&'a Struct),
550 Table(&'a TableOrUnion),
551 Union(&'a TableOrUnion),
552}
553
554pub struct Namespace {
556 modules: HashMap<String, Module>,
557 methods_by_ordinal: HashMap<u64, (String, Weak<Method>)>,
558}
559
560impl Namespace {
561 pub fn new() -> Self {
563 Namespace { modules: HashMap::new(), methods_by_ordinal: HashMap::new() }
564 }
565
566 pub fn load(&mut self, data: &str) -> Result<()> {
568 let new_mod: Module = serde_json::from_str(data)?;
569
570 for protocol in new_mod.protocol_declarations.values() {
571 for method in protocol.methods.values() {
572 self.methods_by_ordinal
573 .insert(method.ordinal, (protocol.name(), Arc::downgrade(method)));
574 }
575 }
576
577 self.modules.insert(new_mod.name.clone(), new_mod);
578 Ok(())
579 }
580
581 pub fn lookup(&self, name: &str) -> Result<LookupResult<'_>> {
583 let halves: Vec<_> = name.split('/').collect();
584
585 if halves.len() != 2 {
586 return Err(Error::LibraryError(format!(
587 "Wrong number of path components in {}, expected 2",
588 name
589 )));
590 }
591
592 let module: &Module = match self.modules.get(halves[0]) {
593 Some(x) => x,
594 None => return Err(Error::LibraryError(format!("Module {} not found!", halves[0]))),
595 };
596
597 match module.declarations.get(name).map(|x| x.as_ref()) {
598 Some("bits") => match module.bits_declarations.get(name) {
599 Some(x) => Ok(LookupResult::Bits(x)),
600 None => {
601 Err(Error::LibraryError(format!("{} not found in bits declarations!", name)))
602 }
603 },
604 Some("enum") => match module.enum_declarations.get(name) {
605 Some(x) => Ok(LookupResult::Enum(x)),
606 None => {
607 Err(Error::LibraryError(format!("{} not found in enum declarations!", name)))
608 }
609 },
610 Some("protocol") => match module.protocol_declarations.get(name) {
611 Some(x) => Ok(LookupResult::Protocol(x)),
612 None => Err(Error::LibraryError(format!(
613 "{} not found in protocol declarations!",
614 name
615 ))),
616 },
617 Some("struct") => match module.struct_declarations.get(name) {
618 Some(x) => Ok(LookupResult::Struct(x)),
619 None => {
620 Err(Error::LibraryError(format!("{} not found in struct declarations!", name)))
621 }
622 },
623 Some("table") => match module.table_declarations.get(name) {
624 Some(x) => Ok(LookupResult::Table(x)),
625 None => {
626 Err(Error::LibraryError(format!("{} not found in table declarations!", name)))
627 }
628 },
629 Some("union") => match module.union_declarations.get(name) {
630 Some(x) => Ok(LookupResult::Union(x)),
631 None => {
632 Err(Error::LibraryError(format!("{} not found in union declarations!", name)))
633 }
634 },
635 Some(x) => Err(Error::LibraryError(format!("{} has unknown type {}!", name, x))),
636 None => Err(Error::LibraryError(format!("{} not found in {}!", name, module.name))),
637 }
638 }
639
640 pub fn inherits(&self, a: &str, b: &str) -> bool {
642 if a == b {
643 return true;
644 }
645
646 let Ok(LookupResult::Protocol(protocol)) = self.lookup(a) else {
647 return false;
648 };
649
650 for composed_protocol in protocol.composed_protocols.iter() {
651 if self.inherits(composed_protocol, b) {
652 return true;
653 }
654 }
655
656 false
657 }
658
659 pub fn lookup_method_ordinal(&self, ordinal: u64) -> Result<(String, Arc<Method>)> {
661 self.methods_by_ordinal
662 .get(&ordinal)
663 .and_then(|(x, y)| y.upgrade().map(|y| (x.clone(), y)))
664 .ok_or_else(|| Error::LibraryError(format!("No method with ordinal {}", ordinal)))
665 }
666}