Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing field "StructuredType" #435

Closed
CrayfishGo opened this issue Jul 22, 2022 · 1 comment · Fixed by #453
Closed

Missing field "StructuredType" #435

CrayfishGo opened this issue Jul 22, 2022 · 1 comment · Fixed by #453
Labels
bug serde Issues related to mapping from Rust types to XML

Comments

@CrayfishGo
Copy link

Here is my xml file:

<?xml version="1.0" encoding="utf-8" ?>
<opc:TypeDictionary
  xmlns:opc="http://opcfoundation.org/BinarySchema/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ua="http://opcfoundation.org/UA/"
  xmlns:tns="http://opcfoundation.org/UA/"
  DefaultByteOrder="LittleEndian"
  TargetNamespace="http://opcfoundation.org/UA/"
>
  <opc:EnumeratedType Name="NodeIdType" LengthInBits="6">
    <opc:Documentation>The possible encodings for a NodeId value.</opc:Documentation>
    <opc:EnumeratedValue Name="TwoByte" Value="0" />
    <opc:EnumeratedValue Name="FourByte" Value="1" />
    <opc:EnumeratedValue Name="Numeric" Value="2" />
    <opc:EnumeratedValue Name="String" Value="3" />
    <opc:EnumeratedValue Name="Guid" Value="4" />
    <opc:EnumeratedValue Name="ByteString" Value="5" />
  </opc:EnumeratedType>
  
  <opc:StructuredType Name="TwoByteNodeId">
    <opc:Field Name="Identifier" TypeName="opc:Byte" />
  </opc:StructuredType>

  <opc:StructuredType Name="FourByteNodeId">
    <opc:Field Name="NamespaceIndex" TypeName="opc:Byte" />
    <opc:Field Name="Identifier" TypeName="opc:UInt16" />
  </opc:StructuredType>

  <opc:EnumeratedType Name="AxisScaleEnumeration" LengthInBits="32">
    <opc:EnumeratedValue Name="Linear" Value="0" />
    <opc:EnumeratedValue Name="Log" Value="1" />
    <opc:EnumeratedValue Name="Ln" Value="2" />
  </opc:EnumeratedType>

  <opc:EnumeratedType Name="ExceptionDeviationFormat" LengthInBits="32">
    <opc:EnumeratedValue Name="AbsoluteValue" Value="0" />
    <opc:EnumeratedValue Name="PercentOfValue" Value="1" />
    <opc:EnumeratedValue Name="PercentOfRange" Value="2" />
    <opc:EnumeratedValue Name="PercentOfEURange" Value="3" />
    <opc:EnumeratedValue Name="Unknown" Value="4" />
  </opc:EnumeratedType>
</opc:TypeDictionary>

My rust code:

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct TypeDictionary {
    #[serde(rename = "StructuredType")]
    pub struct_types: Vec<StructType>,

    #[serde(rename = "EnumeratedType")]
    pub enum_types: Vec<EnumType>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct StructType {
    #[serde(rename = "Name")]
    pub name: String,

    #[serde(rename = "Documentation")]
    pub documentation: Option<String>,

    #[serde(rename = "BaseType")]
    pub base_type: Option<String>,

    #[serde(rename = "Field", default)]
    pub fields: Vec<StructField>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct StructField {
    #[serde(rename = "Name", default)]
    pub name: String,

    #[serde(rename = "TypeName")]
    pub type_name: String,

    #[serde(rename = "Length")]
    pub length: Option<String>,

    #[serde(rename = "LengthField")]
    pub length_field: Option<String>,

    #[serde(rename = "SwitchField")]
    pub switch_field: Option<String>,

    #[serde(rename = "SwitchValue")]
    pub switch_value: Option<String>,

    #[serde(skip)]
    pub is_enum: bool,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct EnumType {
    #[serde(rename = "Name", default)]
    pub name: String,

    #[serde(rename = "Documentation")]
    pub documentation: Option<String>,

    #[serde(rename = "LengthInBits")]
    pub length_in_bits: Option<String>,

    #[serde(rename = "EnumeratedValue")]
    pub enumerated_values: Vec<EnumValue>,

    #[serde(rename = "IsOptionSet")]
    pub is_option_set: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct EnumValue {
    #[serde(rename = "Name", default)]
    pub name: String,

    #[serde(rename = "Value")]
    pub value: String,
}

pub fn gen_types<P: AsRef<Path> + Copy>(path: P) {
    let p = Path::new("../schemas/1.0.4/Opc.Ua.Types.bsd.xml");
    let data = fs::read_to_string(p);
    let r: Result<TypeDictionary, DeError> = quick_xml::de::from_str(data.unwrap().as_str());
    match r {
        Ok(td) => {
            let struct_types = td.struct_types;
            let enum_types = td.enum_types;
            gen_structs(struct_types, path);
            gen_enums(enum_types, path.as_ref());
        }
        Err(e) => {
            println!("{:?}", e)
        }
    }
}

Then an error happend: Custom("missing fieldStructuredType")

@Mingun
Copy link
Collaborator

Mingun commented Jul 23, 2022

The problem in the nested enumerated_values list. Minimal reproducable example:

#[test]
fn nested_list() {
    #[derive(Debug, Deserialize, PartialEq)]
    pub struct Root {
        pub list1: Vec<()>,
        pub list2: Vec<List>,
    }

    #[derive(Debug, Deserialize, PartialEq)]
    pub struct List {
        pub inner_list: Vec<()>,
    }

    from_str::<Root>(
        r#"
    <?xml version="1.0" encoding="utf-8" ?>
    <root>
      <list2><inner_list/></list2>
      <list1/>
      <list2><inner_list/></list2>
    </root>
    "#,
    )
    .unwrap();
}
failures:

---- nested_list stdout ----
[tests\serde-de.rs:18] s = "\n    <?xml version=\"1.0\" encoding=\"utf-8\" ?>\n    <root>\n      <list2><inner_list/></list2>\n      <list1/>\n      <list2><inner_list/></list2>\n    </root>\n    "
thread 'nested_list' panicked at 'called `Result::unwrap()` on an `Err` value: Custom("missing field `list1`")', tests\serde-de.rs:4890:6
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

@Mingun Mingun added bug serde Issues related to mapping from Rust types to XML labels Jul 23, 2022
@Mingun Mingun mentioned this issue Aug 3, 2022
18 tasks
Mingun added a commit to Mingun/quick-xml that referenced this issue Aug 6, 2022
Mingun added a commit to Mingun/quick-xml that referenced this issue Aug 7, 2022
Mingun added a commit to Mingun/quick-xml that referenced this issue Aug 7, 2022
dralley added a commit that referenced this issue Aug 7, 2022
Fix #435: replay only events from time of creating SeqAccess struct
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug serde Issues related to mapping from Rust types to XML
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants