ligen_core/ir/
constant.rs

1use crate::ir::{Identifier, Literal, Type};
2use std::convert::TryFrom;
3use syn::{ImplItemConst, ItemConst};
4
5#[derive(Debug, PartialEq, Clone)]
6/// Constant Struct
7pub struct Constant {
8    /// identifier field
9    pub identifier: Identifier,
10    /// type_ field
11    pub type_: Type,
12    /// literal field
13    pub literal: Literal,
14}
15
16impl From<ImplItemConst> for Constant {
17    fn from(item_const: ImplItemConst) -> Self {
18        if let syn::Expr::Lit(syn::ExprLit { lit, .. }) = item_const.expr {
19            Self {
20                identifier: Identifier::from(item_const.ident.clone()),
21                type_: Type::try_from(item_const.ty).expect("Failed to convert from Type"),
22                literal: Literal::from(lit),
23            }
24        } else {
25            panic!("Undefined Constant inside Impl block");
26        }
27    }
28}
29
30impl From<ItemConst> for Constant {
31    fn from(item_const: ItemConst) -> Self {
32        if let syn::Expr::Lit(syn::ExprLit { lit, .. }) = *item_const.expr {
33            Self {
34                identifier: Identifier::from(item_const.ident.clone()),
35                type_: Type::try_from(*item_const.ty).expect("Failed to convert from Type"),
36                literal: Literal::from(lit),
37            }
38        } else {
39            panic!("Undefined Constant");
40        }
41    }
42}
43
44#[cfg(test)]
45mod test {
46    use super::{Constant, Identifier, ImplItemConst, ItemConst, Type};
47    use crate::ir::{Literal, Reference, ReferenceKind};
48    use quote::quote;
49    use syn::parse_quote::parse;
50
51    #[test]
52    fn impl_const_impl() {
53        assert_eq!(
54            Constant::from(parse::<ImplItemConst>(quote! {const a: &str = "test";})),
55            Constant {
56                identifier: Identifier::new("a"),
57                type_: Type::Reference(
58                    Reference {
59                        kind: ReferenceKind::Borrow,
60                        is_constant: true,
61                        type_: Box::new(Type::Compound(Identifier::new("str").into()))
62                    }
63                ),
64                literal: Literal::String(String::from("test"))
65            }
66        );
67    }
68
69    #[test]
70    fn impl_const() {
71        assert_eq!(
72            Constant::from(parse::<ItemConst>(quote! {const a: &str = "test";})),
73            Constant {
74                identifier: Identifier::new("a"),
75                type_: Type::Reference(
76                    Reference {
77                        kind: ReferenceKind::Borrow,
78                        is_constant: true,
79                        type_: Box::new(Type::Compound(Identifier::new("str").into()))
80                    }
81                ),
82                literal: Literal::String(String::from("test"))
83            }
84        );
85    }
86}