Skip to main content

rue_types/types/
atom.rs

1use std::{borrow::Cow, fmt};
2
3use clvmr::Allocator;
4use derive_more::Display;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display)]
7pub enum AtomSemantic {
8    #[display("Atom")]
9    Any,
10
11    #[display("Bytes")]
12    Bytes,
13
14    #[display("String")]
15    String,
16
17    #[display("Int")]
18    Int,
19
20    #[display("PublicKey")]
21    PublicKey,
22
23    #[display("Signature")]
24    Signature,
25
26    #[display("K1PublicKey")]
27    K1PublicKey,
28
29    #[display("K1Signature")]
30    K1Signature,
31
32    #[display("R1PublicKey")]
33    R1PublicKey,
34
35    #[display("R1Signature")]
36    R1Signature,
37
38    #[display("Bool")]
39    Bool,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Hash)]
43pub enum AtomRestriction {
44    Value(Cow<'static, [u8]>),
45    Length(usize),
46}
47
48#[derive(Debug, Clone)]
49pub struct Atom {
50    pub semantic: AtomSemantic,
51    pub restriction: Option<AtomRestriction>,
52}
53
54impl Atom {
55    pub const ANY: Self = Self::new(AtomSemantic::Any, None);
56    pub const NIL: Self = Self::new(
57        AtomSemantic::Bytes,
58        Some(AtomRestriction::Value(Cow::Borrowed(&[]))),
59    );
60    pub const FALSE: Self = Self::new(
61        AtomSemantic::Bool,
62        Some(AtomRestriction::Value(Cow::Borrowed(&[]))),
63    );
64    pub const TRUE: Self = Self::new(
65        AtomSemantic::Bool,
66        Some(AtomRestriction::Value(Cow::Borrowed(&[1]))),
67    );
68    pub const BYTES: Self = Self::new(AtomSemantic::Bytes, None);
69    pub const BYTES_32: Self = Self::new(AtomSemantic::Bytes, Some(AtomRestriction::Length(32)));
70    pub const STRING: Self = Self::new(AtomSemantic::String, None);
71    pub const PUBLIC_KEY: Self =
72        Self::new(AtomSemantic::PublicKey, Some(AtomRestriction::Length(48)));
73    pub const SIGNATURE: Self =
74        Self::new(AtomSemantic::Signature, Some(AtomRestriction::Length(96)));
75    pub const K1_PUBLIC_KEY: Self =
76        Self::new(AtomSemantic::K1PublicKey, Some(AtomRestriction::Length(33)));
77    pub const K1_SIGNATURE: Self =
78        Self::new(AtomSemantic::K1Signature, Some(AtomRestriction::Length(64)));
79    pub const R1_PUBLIC_KEY: Self =
80        Self::new(AtomSemantic::R1PublicKey, Some(AtomRestriction::Length(33)));
81    pub const R1_SIGNATURE: Self =
82        Self::new(AtomSemantic::Signature, Some(AtomRestriction::Length(64)));
83    pub const INT: Self = Self::new(AtomSemantic::Int, None);
84
85    pub const fn new(semantic: AtomSemantic, restriction: Option<AtomRestriction>) -> Self {
86        Self {
87            semantic,
88            restriction,
89        }
90    }
91}
92
93impl fmt::Display for Atom {
94    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        match self.semantic {
96            AtomSemantic::Any => write!(f, "Atom"),
97            AtomSemantic::Bytes => match &self.restriction {
98                None => write!(f, "Bytes"),
99                Some(AtomRestriction::Length(length)) => {
100                    if *length == 32 {
101                        write!(f, "Bytes32")
102                    } else {
103                        write!(f, "Bytes")
104                    }
105                }
106                Some(AtomRestriction::Value(value)) => {
107                    if value.is_empty() {
108                        write!(f, "nil")
109                    } else {
110                        write!(f, "0x{}", hex::encode(value))
111                    }
112                }
113            },
114            AtomSemantic::String => match &self.restriction {
115                None | Some(AtomRestriction::Length(_)) => {
116                    write!(f, "String")
117                }
118                Some(AtomRestriction::Value(value)) => {
119                    write!(f, "\"{}\"", String::from_utf8_lossy(value))
120                }
121            },
122            AtomSemantic::Int => match &self.restriction {
123                None | Some(AtomRestriction::Length(_)) => write!(f, "Int"),
124                Some(AtomRestriction::Value(value)) => {
125                    let mut allocator = Allocator::new();
126                    let ptr = allocator.new_atom(value).unwrap();
127                    let bigint = allocator.number(ptr);
128                    write!(f, "{bigint}")
129                }
130            },
131            AtomSemantic::PublicKey => write!(f, "PublicKey"),
132            AtomSemantic::Signature => write!(f, "Signature"),
133            AtomSemantic::K1PublicKey => write!(f, "K1PublicKey"),
134            AtomSemantic::K1Signature => write!(f, "K1Signature"),
135            AtomSemantic::R1PublicKey => write!(f, "R1PublicKey"),
136            AtomSemantic::R1Signature => write!(f, "R1Signature"),
137            AtomSemantic::Bool => match &self.restriction {
138                None | Some(AtomRestriction::Length(_)) => write!(f, "Bool"),
139                Some(AtomRestriction::Value(value)) => {
140                    if value.is_empty() {
141                        write!(f, "false")
142                    } else if value.as_ref() == [1] {
143                        write!(f, "true")
144                    } else {
145                        write!(f, "Bool")
146                    }
147                }
148            },
149        }
150    }
151}