pub fn create_rust_wrapper(
    config_decl: &ConfigDecl,
    fidl_library_name: String,
) -> Result<String, SourceGenError> {
    let fidl_library_name =
        format!("fidl_{}", fidl_library_name.replace('.', "_").to_ascii_lowercase());
    let fidl_library_name = parse_str::<Ident>(&fidl_library_name)
        .map_err(|source| SourceGenError::InvalidIdentifier { input: fidl_library_name, source })?;
    let ConfigChecksum::Sha256(expected_checksum) = &config_decl.checksum;

    let expected_checksum =
        expected_checksum.into_iter().map(|b| Literal::from_str(&format!("{:#04x}", b)).unwrap());

    let mut field_declarations = vec![];
    let mut field_conversions = vec![];

    let mut record_to_inspect_ops = vec![];
    let mut inspect_uses = vec![quote!(Node)];

    let mut needs_array_property = false;
    let mut needs_arithmetic_array_property = false;

    for field in &config_decl.fields {
        let RustTokens { decl, conversion, record_to_inspect } =
            get_rust_tokens(&field.key, &field.type_)?;

        if let ConfigValueType::Vector {
            nested_type: ConfigNestedValueType::String { .. }, ..
        } = &field.type_
        {
            needs_array_property = true;
        } else if let ConfigValueType::Vector { .. } = &field.type_ {
            needs_arithmetic_array_property = true;
        }

        record_to_inspect_ops.push(record_to_inspect);
        field_declarations.push(decl);
        field_conversions.push(conversion)
    }

    if needs_arithmetic_array_property {
        inspect_uses.push(quote!(ArithmeticArrayProperty))
    }
    if needs_array_property {
        inspect_uses.push(quote!(ArrayProperty))
    }

    let stream = quote! {
        use #fidl_library_name::Config as FidlConfig;
        use fidl::encoding::decode_persistent;
        use fuchsia_inspect::{#(#inspect_uses),*};
        use fuchsia_runtime::{take_startup_handle, HandleInfo, HandleType};
        use fuchsia_zircon as zx;

        pub struct Config {
            #(#field_declarations),*
        }

        impl Config {
            pub fn from_args() -> Self {
                let config_vmo: zx::Vmo = take_startup_handle(HandleInfo::new(HandleType::ConfigVmo, 0))
                    .expect("must have been provided with a config vmo")
                    .into();
                let config_size = config_vmo.get_content_size().expect("must be able to read config vmo content size");
                assert_ne!(config_size, 0, "config vmo must be non-empty");

                let mut config_bytes = Vec::new();
                config_bytes.resize(config_size as usize, 0);
                config_vmo.read(&mut config_bytes, 0).expect("must be able to read config vmo");

                let checksum_length = u16::from_le_bytes([config_bytes[0], config_bytes[1]]) as usize;
                let fidl_start = 2 + checksum_length;
                let observed_checksum = &config_bytes[2..fidl_start];
                let expected_checksum = vec![#(#expected_checksum),*];

                assert_eq!(observed_checksum, expected_checksum, "checksum from config VMO does not match expected checksum");

                let fidl_config: FidlConfig = decode_persistent(&config_bytes[fidl_start..]).expect("must be able to parse bytes as config FIDL");

                Self {
                    #(#field_conversions),*
                }
            }

            pub fn record_to_inspect(self, root_node: &Node)->Self{
                root_node.record_child("config", |inspector_node| {
                    #(#record_to_inspect_ops)*
                });
                self
            }
        }
    };

    Ok(stream.to_string())
}
/// Create a Rust wrapper file containing all the fields of a config declaration
Create a Rust wrapper file containing all the fields of a config declaration
Create a Rust wrapper file containing all the fields of a config declaration
pub fn create_rust_wrapper(
    config_decl: &ConfigDecl,
    fidl_library_name: String,
) -> Result<String, SourceGenError> {
    let fidl_library_name =
        format!("fidl_{}", fidl_library_name.replace('.', "_").to_ascii_lowercase());
    let fidl_library_name = parse_str::<Ident>(&fidl_library_name)
        .map_err(|source| SourceGenError::InvalidIdentifier { input: fidl_library_name, source })?;
    let ConfigChecksum::Sha256(expected_checksum) = &config_decl.checksum;
    let expected_checksum =
        expected_checksum.into_iter().map(|b| Literal::from_str(&format!("{:#04x}", b)).unwrap());
    let mut field_declarations = vec![];
    let mut field_conversions = vec![];
    let mut record_to_inspect_ops = vec![];
    let mut inspect_uses = vec![quote!(Node)];
    let mut needs_array_property = false;
    let mut needs_arithmetic_array_property = false;
    for field in &config_decl.fields {
        let RustTokens { decl, conversion, record_to_inspect } =
            get_rust_tokens(&field.key, &field.type_)?;
        if let ConfigValueType::Vector {
            nested_type: ConfigNestedValueType::String { .. }, ..
        } = &field.type_
        {
            needs_array_property = true;
        } else if let ConfigValueType::Vector { .. } = &field.type_ {
            needs_arithmetic_array_property = true;
        }
        record_to_inspect_ops.push(record_to_inspect);
        field_declarations.push(decl);
        field_conversions.push(conversion)
    }
    if needs_arithmetic_array_property {
        inspect_uses.push(quote!(ArithmeticArrayProperty))
    }
    if needs_array_property {
        inspect_uses.push(quote!(ArrayProperty))
    }
    let stream = quote! {
        use #fidl_library_name::Config as FidlConfig;
        use fidl::encoding::decode_persistent;
        use fuchsia_inspect::{#(#inspect_uses),*};
        use fuchsia_runtime::{take_startup_handle, HandleInfo, HandleType};
        use fuchsia_zircon as zx;
        pub struct Config {
            #(#field_declarations),*
        }
        impl Config {
            pub fn from_args() -> Self {
                let config_vmo: zx::Vmo = take_startup_handle(HandleInfo::new(HandleType::ConfigVmo, 0))
                    .expect("must have been provided with a config vmo")
                    .into();
                let config_size = config_vmo.get_content_size().expect("must be able to read config vmo content size");
                assert_ne!(config_size, 0, "config vmo must be non-empty");
                let mut config_bytes = Vec::new();
                config_bytes.resize(config_size as usize, 0);
                config_vmo.read(&mut config_bytes, 0).expect("must be able to read config vmo");
                let checksum_length = u16::from_le_bytes([config_bytes[0], config_bytes[1]]) as usize;
                let fidl_start = 2 + checksum_length;
                let observed_checksum = &config_bytes[2..fidl_start];
                let expected_checksum = vec![#(#expected_checksum),*];
                assert_eq!(observed_checksum, expected_checksum, "checksum from config VMO does not match expected checksum");
                let fidl_config: FidlConfig = decode_persistent(&config_bytes[fidl_start..]).expect("must be able to parse bytes as config FIDL");
                Self {
                    #(#field_conversions),*
                }
            }
            pub fn record_to_inspect(self, root_node: &Node)->Self{
                root_node.record_child("config", |inspector_node| {
                    #(#record_to_inspect_ops)*
                });
                self
            }
        }
    };
    Ok(stream.to_string())
}
pub fn create_rust_wrapper ( config_decl : & ConfigDecl , fidl_library_name : String , ) -> Result < String , SourceGenError > { let fidl_library_name = format ! ( " " fidl_library_name replace ( '.' " " ) to_ascii_lowercase ( ) ) ; let fidl_library_name = parse_str :: < Ident > ( & fidl_library_name ) . map_err ( | source | SourceGenError :: InvalidIdentifier { input : fidl_library_name , source } ) ? ; let ConfigChecksum :: Sha256 ( expected_checksum ) = & config_decl . checksum ; let expected_checksum = expected_checksum . into_iter ( ) . map ( | b | Literal :: from_str ( & format ! ( " " b ) ) . unwrap ( ) ) ; let mut field_declarations = vec ! [ ] ; let mut field_conversions = vec ! [ ] ; let mut record_to_inspect_ops = vec ! [ ] ; let mut inspect_uses = vec ! [ quote ( Node ) ] ; let mut needs_array_property = false ; let mut needs_arithmetic_array_property = false ; for field in & config_decl . fields { let RustTokens { decl , conversion , record_to_inspect } = get_rust_tokens ( & field . key , & field . type_ ) ? ; if let ConfigValueType :: Vector { nested_type : ConfigNestedValueType :: String { .. } , .. } = & field . type_ { needs_array_property = true ; } else if let ConfigValueType :: Vector { .. } = & field . type_ { needs_arithmetic_array_property = true ; } record_to_inspect_ops . push ( record_to_inspect ) ; field_declarations . push ( decl ) ; field_conversions . push ( conversion ) } if needs_arithmetic_array_property { inspect_uses . push ( quote ! ( ArithmeticArrayProperty ) ) } if needs_array_property { inspect_uses . push ( quote ! ( ArrayProperty ) ) } let stream = quote ! { use fidl_library_name Config as FidlConfig use fidl encoding decode_persistent use fuchsia_inspect { ( inspect_uses ) } use fuchsia_runtime { take_startup_handle HandleInfo HandleType } use fuchsia_zircon as zx pub struct Config { ( field_declarations ) } impl Config { pub fn from_args ( ) Self { let config_vmo zx Vmo take_startup_handle ( HandleInfo new ( HandleType ConfigVmo 0 ) ) expect ( " " ) into ( ) let config_size config_vmo get_content_size ( ) expect ( " " ) assert_ne ( config_size 0 " " ) let mut config_bytes Vec new ( ) config_bytes resize ( config_size as usize 0 ) config_vmo read ( mut config_bytes 0 ) expect ( " " ) let checksum_length u16 from_le_bytes ( [ config_bytes [ 0 ] config_bytes [ 1 ] ] ) as usize let fidl_start 2 checksum_length let observed_checksum config_bytes [ 2 fidl_start ] let expected_checksum vec [ ( expected_checksum ) ] assert_eq ( observed_checksum expected_checksum " " ) let fidl_config FidlConfig decode_persistent ( config_bytes [ fidl_start ] ) expect ( " " ) Self { ( field_conversions ) } } pub fn record_to_inspect ( self root_node Node ) Self { root_node record_child ( " " inspector_node { ( record_to_inspect_ops ) } ) self } } } ; Ok ( stream . to_string ( ) ) }
Create a Rust wrapper file containing all the fields of a config declaration
Create a Rust wrapper file containing all the fields of a config declaration
config_decl
&ConfigDecl
fidl_library_name
String
config_decl
&ConfigDecl
fidl_library_name
String