codama-nodes 0.9.3

Node specifications and helpers for the Codama standard
Documentation
use crate::{
    CamelCaseString, DefinedTypeLinkNode, EnumValueNode, EnumValuePayload, StructValueNode,
    TupleValueNode,
};

impl EnumValueNode {
    pub fn new<T, U>(r#enum: T, variant: U, value: Option<EnumValuePayload>) -> Self
    where
        T: Into<DefinedTypeLinkNode>,
        U: Into<CamelCaseString>,
    {
        Self {
            variant: variant.into(),
            r#enum: r#enum.into(),
            value: Box::new(value),
        }
    }

    pub fn empty<T, U>(r#enum: T, variant: U) -> Self
    where
        T: Into<DefinedTypeLinkNode>,
        U: Into<CamelCaseString>,
    {
        Self {
            variant: variant.into(),
            r#enum: r#enum.into(),
            value: Box::new(None),
        }
    }

    pub fn fields<T, U, V>(r#enum: T, variant: U, value: V) -> Self
    where
        T: Into<DefinedTypeLinkNode>,
        U: Into<CamelCaseString>,
        V: Into<StructValueNode>,
    {
        Self {
            variant: variant.into(),
            r#enum: r#enum.into(),
            value: Box::new(Some(EnumValuePayload::Struct(value.into()))),
        }
    }

    pub fn tuple<T, U, V>(r#enum: T, variant: U, value: V) -> Self
    where
        T: Into<DefinedTypeLinkNode>,
        U: Into<CamelCaseString>,
        V: Into<TupleValueNode>,
    {
        Self {
            variant: variant.into(),
            r#enum: r#enum.into(),
            value: Box::new(Some(EnumValuePayload::Tuple(value.into()))),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{NumberValueNode, StringValueNode, StructFieldValueNode};

    #[test]
    fn new() {
        let node = EnumValueNode::new("direction", "north", None);
        assert_eq!(node.r#enum, DefinedTypeLinkNode::new("direction"));
        assert_eq!(node.variant, CamelCaseString::from("north"));
        assert_eq!(*node.value, None);
    }

    #[test]
    fn empty() {
        let node = EnumValueNode::empty("command", "exit");
        assert_eq!(node.r#enum, DefinedTypeLinkNode::new("command"));
        assert_eq!(node.variant, CamelCaseString::from("exit"));
        assert_eq!(*node.value, None);
    }

    #[test]
    fn fields() {
        let node = EnumValueNode::fields(
            "command",
            "move",
            vec![
                StructFieldValueNode::new("x", NumberValueNode::new(10)),
                StructFieldValueNode::new("y", NumberValueNode::new(20)),
            ],
        );
        assert_eq!(node.r#enum, DefinedTypeLinkNode::new("command"));
        assert_eq!(node.variant, CamelCaseString::from("move"));
        assert_eq!(
            *node.value,
            Some(EnumValuePayload::Struct(StructValueNode::new(vec![
                StructFieldValueNode::new("x", NumberValueNode::new(10)),
                StructFieldValueNode::new("y", NumberValueNode::new(20)),
            ])))
        );
    }

    #[test]
    fn tuple() {
        let node = EnumValueNode::tuple(
            "command",
            "write",
            vec![StringValueNode::new("Hello World").into()],
        );
        assert_eq!(node.r#enum, DefinedTypeLinkNode::new("command"));
        assert_eq!(node.variant, CamelCaseString::from("write"));
        assert_eq!(
            *node.value,
            Some(EnumValuePayload::Tuple(TupleValueNode::new(vec![
                StringValueNode::new("Hello World").into()
            ])))
        );
    }

    #[test]
    fn to_json() {
        let node = EnumValueNode::empty("command", "exit");
        let json = serde_json::to_string(&node).unwrap();
        assert_eq!(
            json,
            r#"{"kind":"enumValueNode","variant":"exit","enum":{"kind":"definedTypeLinkNode","name":"command"}}"#
        );
    }

    #[test]
    fn from_json() {
        let json = r#"{"kind":"enumValueNode","variant":"exit","enum":{"kind":"definedTypeLinkNode","name":"command"}}"#;
        let node: EnumValueNode = serde_json::from_str(json).unwrap();
        assert_eq!(node, EnumValueNode::empty("command", "exit"));
    }
}