xidl-parser 0.56.0

A IDL codegen.
Documentation
use super::*;
use crate::hir::{
    BinaryOperator, ConstExpr, DecNumber, FloatingPtLiteral, IntegerLiteral, IntegerSign, Literal,
    ScopedName, UnaryOperator,
};

fn int(value: &str) -> ConstExpr {
    ConstExpr::Literal(Literal::IntegerLiteral(IntegerLiteral(value.to_string())))
}

#[test]
fn parse_string_array_and_raw_params_handle_nested_values() {
    assert_eq!(
        parse_string_array(r#""a,b", call(x,y), [left,right], plain, 'x,y'"#),
        vec![
            "\"a,b\"".to_string(),
            "call(x,y)".to_string(),
            "[left,right]".to_string(),
            "plain".to_string(),
            "'x,y'".to_string(),
        ]
    );

    assert_eq!(parse_raw_params(""), Vec::<(String, String)>::new());
    assert_eq!(
        parse_raw_params(r#""city-id""#),
        vec![("value".to_string(), "city-id".to_string())]
    );
    assert_eq!(
        parse_raw_params(r#"name="X-Trace", scopes=["read","write"], value='literal'"#),
        vec![
            ("name".to_string(), "X-Trace".to_string()),
            ("scopes".to_string(), "[\"read\",\"write\"]".to_string()),
            ("value".to_string(), "literal".to_string()),
        ]
    );
}

#[test]
fn trim_quotes_only_accepts_balanced_single_or_double_quotes() {
    assert_eq!(trim_quotes(r#""hello""#).as_deref(), Some("hello"));
    assert_eq!(trim_quotes("'world'").as_deref(), Some("world"));
    assert_eq!(trim_quotes("plain"), None);
    assert_eq!(trim_quotes("'unterminated"), None);
}

#[test]
fn render_const_expr_covers_scoped_names_literals_unary_and_binary_ops() {
    let scoped = ConstExpr::ScopedName(ScopedName {
        name: vec!["MyModule".to_string(), "MyValue".to_string()],
        is_root: true,
    });
    assert_eq!(render_const_expr(&scoped), "::my_module::my_value");

    let float = ConstExpr::Literal(Literal::FloatingPtLiteral(FloatingPtLiteral {
        sign: Some(IntegerSign::Minus),
        integer: DecNumber("12".to_string()),
        fraction: DecNumber("5".to_string()),
    }));
    assert_eq!(render_const_expr(&float), "-12.5");
    assert_eq!(
        render_const_expr(&ConstExpr::Literal(Literal::CharLiteral("'x'".to_string()))),
        "'x'"
    );
    assert_eq!(
        render_const_expr(&ConstExpr::Literal(Literal::WideCharacterLiteral(
            "L'x'".to_string()
        ))),
        "L'x'"
    );
    assert_eq!(
        render_const_expr(&ConstExpr::Literal(Literal::StringLiteral(
            "\"hi\"".to_string()
        ))),
        "\"hi\""
    );
    assert_eq!(
        render_const_expr(&ConstExpr::Literal(Literal::WideStringLiteral(
            "L\"hi\"".to_string()
        ))),
        "L\"hi\""
    );
    assert_eq!(
        render_const_expr(&ConstExpr::Literal(Literal::BooleanLiteral(true))),
        "true"
    );

    let unary_cases = [
        (UnaryOperator::Add, "(+1)"),
        (UnaryOperator::Sub, "(-1)"),
        (UnaryOperator::Not, "(~1)"),
    ];
    for (op, expected) in unary_cases {
        let expr = ConstExpr::UnaryExpr(op, Box::new(int("1")));
        assert_eq!(render_const_expr(&expr), expected);
    }

    let binary_cases = [
        (BinaryOperator::Or, "(1 | 2)"),
        (BinaryOperator::Xor, "(1 ^ 2)"),
        (BinaryOperator::And, "(1 & 2)"),
        (BinaryOperator::LeftShift, "(1 << 2)"),
        (BinaryOperator::RightShift, "(1 >> 2)"),
        (BinaryOperator::Add, "(1 + 2)"),
        (BinaryOperator::Sub, "(1 - 2)"),
        (BinaryOperator::Mult, "(1 * 2)"),
        (BinaryOperator::Div, "(1 / 2)"),
        (BinaryOperator::Mod, "(1 % 2)"),
    ];
    for (op, expected) in binary_cases {
        let expr = ConstExpr::BinaryExpr(op, Box::new(int("1")), Box::new(int("2")));
        assert_eq!(render_const_expr(&expr), expected);
    }
}