sui_types/object/
option_visitor.rs1use move_core_types::{
7 account_address::AccountAddress, annotated_value::MoveTypeLayout, annotated_visitor as AV,
8 u256::U256, visitor_default,
9};
10
11use crate::base_types::RESOLVED_STD_OPTION;
12
13#[derive(thiserror::Error, Debug)]
15#[error("Unexpected type")]
16pub struct Error;
17
18pub struct OptionVisitor<'a, T>(pub &'a mut T);
21
22impl<'b, 'l, T, E> AV::Visitor<'b, 'l> for OptionVisitor<'_, T>
23where
24 T: AV::Visitor<'b, 'l, Error = E>,
25 E: From<Error> + From<AV::Error>,
26{
27 type Value = Option<T::Value>;
28 type Error = E;
29
30 visitor_default! { <'b, 'l> u8, u16, u32, u64, u128, u256 = Err(Error.into()) }
31 visitor_default! { <'b, 'l> bool, address, signer, variant = Err(Error.into()) }
32
33 fn visit_vector(
34 &mut self,
35 driver: &mut AV::VecDriver<'_, 'b, 'l>,
36 ) -> Result<Self::Value, Self::Error> {
37 match driver.len() {
38 0 => Ok(None),
39 1 => driver.next_element(self.0),
40 _ => Err(Error.into()),
41 }
42 }
43
44 fn visit_struct(
45 &mut self,
46 driver: &mut AV::StructDriver<'_, 'b, 'l>,
47 ) -> Result<Self::Value, Self::Error> {
48 if is_option(driver.struct_layout()) {
49 driver
50 .next_field(self)?
51 .ok_or_else(|| Error.into())
52 .map(|(_, option)| option)
53 } else {
54 Err(Error.into())
55 }
56 }
57}
58
59fn is_option(struct_layout: &move_core_types::annotated_value::MoveStructLayout) -> bool {
61 let ty = &struct_layout.type_;
62
63 if (&ty.address, ty.module.as_ref(), ty.name.as_ref()) != RESOLVED_STD_OPTION {
64 return false;
65 }
66
67 if ty.type_params.len() != 1 {
68 return false;
69 }
70
71 let Some(type_param) = ty.type_params.first() else {
72 return false;
73 };
74
75 if struct_layout.fields.len() != 1 {
76 return false;
77 }
78
79 let Some(field) = struct_layout.fields.first() else {
80 return false;
81 };
82
83 if field.name.as_str() != "vec" {
84 return false;
85 }
86
87 match &field.layout {
88 MoveTypeLayout::Vector(elem) => {
89 if !elem.is_type(type_param) {
90 return false;
91 }
92 }
93 _ => return false,
94 }
95
96 true
97}