Skip to main content

neo_types/
value.rs

1// Copyright (c) 2025-2026 R3E Network
2// Licensed under the MIT License
3
4use crate::array::NeoArray;
5use crate::boolean::NeoBoolean;
6use crate::bytestring::NeoByteString;
7use crate::integer::NeoInteger;
8use crate::map::NeoMap;
9use crate::string::NeoString;
10
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14// Standard library imports - grouped together
15use std::string::String;
16use std::vec::Vec;
17
18/// Neo N3 Struct type
19#[derive(Debug, Clone, PartialEq, Eq)]
20#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
21pub struct NeoStruct {
22    fields: Vec<(String, NeoValue)>,
23}
24
25impl NeoStruct {
26    pub fn new() -> Self {
27        Self { fields: Vec::new() }
28    }
29
30    pub fn with_field(mut self, name: &str, value: NeoValue) -> Self {
31        self.fields.push((name.to_string(), value));
32        self
33    }
34
35    pub fn get_field(&self, name: &str) -> Option<&NeoValue> {
36        self.fields
37            .iter()
38            .find(|(field_name, _)| field_name == name)
39            .map(|(_, value)| value)
40    }
41
42    pub fn set_field(&mut self, name: &str, value: NeoValue) {
43        if let Some((_, field_value)) = self
44            .fields
45            .iter_mut()
46            .find(|(field_name, _)| field_name == name)
47        {
48            *field_value = value;
49        } else {
50            self.fields.push((name.to_string(), value));
51        }
52    }
53
54    pub fn insert(&mut self, name: NeoString, value: NeoValue) {
55        self.set_field(name.as_str(), value);
56    }
57
58    pub fn len(&self) -> usize {
59        self.fields.len()
60    }
61
62    pub fn is_empty(&self) -> bool {
63        self.fields.is_empty()
64    }
65
66    pub fn iter(&self) -> impl Iterator<Item = (&str, &NeoValue)> {
67        self.fields
68            .iter()
69            .map(|(name, value)| (name.as_str(), value))
70    }
71}
72
73impl Default for NeoStruct {
74    fn default() -> Self {
75        Self::new()
76    }
77}
78
79/// Neo N3 Value type (union of all Neo types)
80#[derive(Debug, Clone, PartialEq, Eq)]
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82pub enum NeoValue {
83    Integer(NeoInteger),
84    Boolean(NeoBoolean),
85    ByteString(NeoByteString),
86    String(NeoString),
87    Array(NeoArray<NeoValue>),
88    Map(NeoMap<NeoValue, NeoValue>),
89    Struct(NeoStruct),
90    Null,
91}
92
93impl NeoValue {
94    pub fn is_null(&self) -> bool {
95        matches!(self, NeoValue::Null)
96    }
97
98    pub fn as_integer(&self) -> Option<&NeoInteger> {
99        match self {
100            NeoValue::Integer(i) => Some(i),
101            _ => None,
102        }
103    }
104
105    pub fn as_boolean(&self) -> Option<NeoBoolean> {
106        match self {
107            NeoValue::Boolean(b) => Some(*b),
108            _ => None,
109        }
110    }
111
112    pub fn as_byte_string(&self) -> Option<&NeoByteString> {
113        match self {
114            NeoValue::ByteString(bs) => Some(bs),
115            _ => None,
116        }
117    }
118
119    pub fn as_string(&self) -> Option<&NeoString> {
120        match self {
121            NeoValue::String(s) => Some(s),
122            _ => None,
123        }
124    }
125
126    pub fn as_array(&self) -> Option<&NeoArray<NeoValue>> {
127        match self {
128            NeoValue::Array(a) => Some(a),
129            _ => None,
130        }
131    }
132
133    pub fn as_map(&self) -> Option<&NeoMap<NeoValue, NeoValue>> {
134        match self {
135            NeoValue::Map(m) => Some(m),
136            _ => None,
137        }
138    }
139
140    pub fn as_struct(&self) -> Option<&NeoStruct> {
141        match self {
142            NeoValue::Struct(s) => Some(s),
143            _ => None,
144        }
145    }
146}
147
148impl From<NeoInteger> for NeoValue {
149    fn from(value: NeoInteger) -> Self {
150        NeoValue::Integer(value)
151    }
152}
153
154impl From<i64> for NeoValue {
155    fn from(value: i64) -> Self {
156        NeoValue::Integer(NeoInteger::new(value))
157    }
158}
159
160impl From<NeoBoolean> for NeoValue {
161    fn from(value: NeoBoolean) -> Self {
162        NeoValue::Boolean(value)
163    }
164}
165
166impl From<bool> for NeoValue {
167    fn from(value: bool) -> Self {
168        NeoValue::Boolean(NeoBoolean::new(value))
169    }
170}
171
172impl From<NeoByteString> for NeoValue {
173    fn from(value: NeoByteString) -> Self {
174        NeoValue::ByteString(value)
175    }
176}
177
178impl From<NeoString> for NeoValue {
179    fn from(value: NeoString) -> Self {
180        NeoValue::String(value)
181    }
182}
183
184impl From<NeoArray<NeoValue>> for NeoValue {
185    fn from(value: NeoArray<NeoValue>) -> Self {
186        NeoValue::Array(value)
187    }
188}
189
190impl From<NeoMap<NeoValue, NeoValue>> for NeoValue {
191    fn from(value: NeoMap<NeoValue, NeoValue>) -> Self {
192        NeoValue::Map(value)
193    }
194}
195
196impl From<NeoStruct> for NeoValue {
197    fn from(value: NeoStruct) -> Self {
198        NeoValue::Struct(value)
199    }
200}