cameleon-genapi 0.1.8

cameleon-genapi provides parser and interpreter of GenApi XML.
Documentation
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use tracing::debug;

use crate::{
    builder::{CacheStoreBuilder, NodeStoreBuilder, ValueStoreBuilder},
    elem_type::ImmOrPNode,
    BooleanNode,
};

use super::{
    elem_name::{BOOLEAN, OFF_VALUE, ON_VALUE, P_SELECTED, STREAMABLE},
    xml, Parse,
};

impl Parse for BooleanNode {
    #[tracing::instrument(level = "trace", skip(node_builder, value_builder, cache_builder))]
    fn parse(
        node: &mut xml::Node,
        node_builder: &mut impl NodeStoreBuilder,
        value_builder: &mut impl ValueStoreBuilder,
        cache_builder: &mut impl CacheStoreBuilder,
    ) -> Self {
        debug!("start parsing `BooleanNode`");
        debug_assert_eq!(node.tag_name(), BOOLEAN);

        let attr_base = node.parse(node_builder, value_builder, cache_builder);
        let elem_base = node.parse(node_builder, value_builder, cache_builder);

        let streamable = node
            .parse_if(STREAMABLE, node_builder, value_builder, cache_builder)
            .unwrap_or_default();
        let value: ImmOrPNode<bool> = node.parse(node_builder, value_builder, cache_builder);
        let on_value: i64 = node
            .parse_if(ON_VALUE, node_builder, value_builder, cache_builder)
            .unwrap_or(1);
        let off_value: i64 = node
            .parse_if(OFF_VALUE, node_builder, value_builder, cache_builder)
            .unwrap_or(0);
        let p_selected = node.parse_while(P_SELECTED, node_builder, value_builder, cache_builder);

        let value = match value {
            ImmOrPNode::Imm(imm) => {
                let i = if imm { on_value } else { off_value };
                let id = value_builder.store(i);
                ImmOrPNode::Imm(id)
            }
            ImmOrPNode::PNode(pnode) => ImmOrPNode::PNode(pnode),
        };

        Self {
            attr_base,
            elem_base,
            streamable,
            value,
            on_value,
            off_value,
            p_selected,
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::{elem_type::ImmOrPNode, store::ValueStore};

    use super::{super::utils::tests::parse_default, *};

    #[test]
    fn test_boolean_node_with_p_node() {
        let xml = r#"
            <Boolean Name="TestNode">
                <pValue>N<!--comment here-->ode</pValue>
                <OnValue>10</OnValue>
                <OffValue>0</OffValue>
            </Boolean>
            "#;

        let (node, mut node_builder, ..): (BooleanNode, _, _, _) = parse_default(xml);
        assert_eq!(
            node.value_elem(),
            ImmOrPNode::PNode(node_builder.get_or_intern("Node"))
        );
        assert_eq!(node.on_value(), 10);
        assert_eq!(node.off_value(), 0);
    }

    #[test]
    fn test_boolean_node_with_imm() {
        let xml1 = r#"
            <Boolean Name="TestNode">
                <Value>true</Value>
                <OnValue>10</OnValue>
                <OffValue>0</OffValue>
            </Boolean>
            "#;

        let (node, _, value_builder, ..): (BooleanNode, _, _, _) = parse_default(xml1);
        let value1 = value_builder
            .integer_value(node.value_elem().imm().unwrap())
            .unwrap();
        assert_eq!(value1, node.on_value());

        let xml2 = r#"
            <Boolean Name="TestNode">
                <Value>false</Value>
                <OnValue>10</OnValue>
                <OffValue>0</OffValue>
            </Boolean>
            "#;

        let (node, _, value_builder2, ..): (BooleanNode, _, _, _) = parse_default(xml2);
        let value2 = value_builder2
            .integer_value(node.value_elem().imm().unwrap())
            .unwrap();
        assert_eq!(value2, node.off_value());
    }
}