flow_value/
lib.rs

1//! This crate contains [`Value`], an enum representing all values that can be used as
2//! node's input and output, and utilities for working with [`Value`].
3//!
4//! Common operations:
5//! - Converting [`Value`] to Rust types.
6//! - Converting Rust types to [`Value`].
7//! - Receiving [`flow_value::Map`][Map] as node's input.
8//! - Returning [`flow_value::Map`][Map] as node's output.
9//! - Converting [`Value`] to/from JSON to use in HTTP APIs and database.
10//! - Getting and updating nested values with JSON Pointer syntax.
11
12use rust_decimal::prelude::ToPrimitive;
13use schemars::JsonSchema;
14use thiserror::Error as ThisError;
15
16pub use rust_decimal::Decimal;
17
18pub(crate) mod value_type;
19pub use value_type::keys;
20
21pub(crate) const TOKEN: &str = "$V";
22
23mod de;
24pub use de::const_bytes::ConstBytes;
25
26mod ser;
27
28pub mod crud;
29pub mod macros;
30
31pub mod with;
32
33#[cfg(feature = "bincode")]
34pub mod bincode_impl;
35
36// custom serialize and deserialize modules
37pub mod decimal;
38#[cfg(feature = "solana-keypair")]
39#[deprecated]
40pub mod keypair;
41#[cfg(feature = "solana-pubkey")]
42pub mod pubkey;
43#[cfg(feature = "solana-signature")]
44pub mod signature;
45
46/// Interpret a [`Value`] as an instance of type `T`
47///
48/// # Example
49///
50/// ```
51/// use solana_pubkey::{Pubkey, pubkey};
52/// use flow_value::Value;
53///
54/// #[derive(serde::Deserialize)]
55/// pub struct User {
56///     pubkey: Pubkey,
57/// }
58///
59/// let value = Value::Map(flow_value::map! {
60///     "pubkey" => pubkey!("My11111111111111111111111111111111111111111"),
61/// });
62/// flow_value::from_value::<User>(value).unwrap();
63/// ```
64pub fn from_value<T>(value: Value) -> Result<T, Error>
65where
66    T: for<'de> serde::Deserialize<'de>,
67{
68    T::deserialize(value)
69}
70
71/// Interpret a [`Map`] as an instance of type `T`
72///
73/// # Example
74///
75/// ```
76/// use solana_pubkey::{Pubkey, pubkey};
77/// use flow_value::Value;
78///
79/// #[derive(serde::Deserialize)]
80/// pub struct User {
81///     pubkey: Pubkey,
82/// }
83///
84/// let map = flow_value::map! {
85///     "pubkey" => pubkey!("My11111111111111111111111111111111111111111"),
86/// };
87/// flow_value::from_map::<User>(map).unwrap();
88/// ```
89pub fn from_map<T>(map: Map) -> Result<T, Error>
90where
91    T: for<'de> serde::Deserialize<'de>,
92{
93    T::deserialize(Value::Map(map))
94}
95
96/// Convert a `T` into [`Value`].
97///
98/// # Example
99///
100/// ```
101/// use solana_signature::Signature;
102/// use flow_value::Value;
103///
104/// let signature = Signature::default();
105/// let value = flow_value::to_value(&flow_value::Bytes(signature.as_ref())).unwrap();
106/// assert_eq!(value, Value::B64(signature.into()));
107/// ```
108pub fn to_value<T>(t: &T) -> Result<Value, Error>
109where
110    T: serde::Serialize,
111{
112    t.serialize(ser::Serializer)
113}
114
115/// Convert a `T` into [`Map`].
116///
117/// # Example
118///
119/// ```
120/// use flow_value::Value;
121///
122/// let map = flow_value::to_map(&serde_json::json!({"A": "B"})).unwrap();
123/// assert_eq!(map, flow_value::map! { "A" => "B" });
124/// ```
125pub fn to_map<T>(t: &T) -> Result<Map, Error>
126where
127    T: serde::Serialize,
128{
129    to_value(t).and_then(|v| match v {
130        Value::Map(map) => Ok(map),
131        _ => Err(Error::ExpectedMap),
132    })
133}
134
135/// Allow for switching HashMap implementation
136pub type HashMap<K, V> = indexmap::IndexMap<K, V>;
137
138/// Key type of [`Map`]
139pub type Key = String;
140
141pub type Map = self::HashMap<Key, Value>;
142
143/// [`Value`] represents all values that nodes can use as input and output.
144///
145/// # Data Types
146///
147/// - Scalar types:
148///     - Null: [`Value::Null`].
149///     - Boolean: [`Value::Bool`].
150///     - Numbers: [`Value::U64`], [`Value::I64`], [`Value::U128`], [`Value::I128`], [`Value::Decimal`], [`Value::F64`].
151///     - String: [`Value::String`].
152///     - Binary: [`Value::B32`], [`Value::B64`], [`Value::Bytes`].
153/// - Array: [`Value::Array`]
154/// - Map: [`Value::Map`]
155///
156/// # Node Input
157///
158/// Node receives a [`flow_value::Map`][Map] as its input. It is possible to use the map directly, but
159/// it is often preferred to convert it to structs or enums of your choice.
160///
161/// [`Value`] implements [`Deserializer`][serde::Deserializer], therefore it can be converted to
162/// any types supported by Serde. We provide 2 helpers:
163///
164/// - [`flow_value::from_value`][from_value] - [`Value`] to any `T: Deserialize`.
165/// - [`flow_value::from_map`][from_map] - [`Map`] to any `T: Deserialize`.
166///
167/// # Node Output
168///
169/// Node returns a [`flow_value::Map`][Map] as its output.
170///
171/// Building the output directly with [`flow_value::map!`][macro@map] and
172/// [`flow_value::array!`][macro@array] macros:
173/// ```
174/// let value = flow_value::map! {
175///     "customer_name" => "John",
176///     "items" => flow_value::array![1, 2, 3],
177/// };
178/// ```
179///
180/// [`Value`] also implements [`Serializer`][serde::Serializer], you can use
181/// [`flow_value::to_map`][to_map] to convert any type `T: Serialize` into [`value::Map`][Map].
182///
183/// ```
184/// #[derive(serde::Serialize)]
185/// struct Order {
186///     customer_name: String,
187///     items: Vec<i32>,
188/// }
189///
190/// flow_value::to_map(&Order {
191///     customer_name: "John".to_owned(),
192///     items: [1, 2, 3].into(),
193/// })
194/// .unwrap();
195/// ```
196///
197/// # JSON representation
198///
199/// When using [`Value`] in database and HTTP APIs, it is converted to a JSON object:
200///
201/// ```json
202/// {
203///     "<variant identifier>": <data>
204/// }
205/// ```
206///
207/// Identifiers of each enum variant:
208/// - **N**: [`Value::Null`]
209/// - **S**: [`Value::String`]
210/// - **B**: [`Value::Bool`]
211/// - **U**: [`Value::U64`]
212/// - **I**: [`Value::I64`]
213/// - **F**: [`Value::F64`]
214/// - **D**: [`Value::Decimal`]
215/// - **U1**: [`Value::U128`]
216/// - **I1**: [`Value::I128`]
217/// - **B3**: [`Value::B32`]
218/// - **B6**: [`Value::B64`]
219/// - **BY**: [`Value::Bytes`]
220/// - **A**: [`Value::Array`]
221/// - **M**: [`Value::Map`]
222///
223/// See variant's documentation to see how data are encoded.
224///
225/// Use [`serde_json`] to encode and decode [`Value`] as JSON:
226/// ```
227/// use flow_value::Value;
228///
229/// let value = Value::U64(10);
230///
231/// // encode Value to JSON
232/// let json = serde_json::to_string(&value).unwrap();
233/// assert_eq!(json, r#"{"U":"10"}"#);
234///
235/// // decode JSON to Value
236/// let value1 = serde_json::from_str::<Value>(&json).unwrap();
237/// assert_eq!(value1, value);
238/// ```
239#[derive(Clone, PartialEq, Default)]
240// #[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
241pub enum Value {
242    /// JSON representation:
243    /// ```json
244    /// { "N": 0 }
245    /// ```
246    #[default]
247    Null,
248    /// UTF-8 string.
249    ///
250    /// JSON representation:
251    /// ```json
252    /// { "S": "hello" }
253    /// ```
254    String(String),
255    /// JSON representation:
256    /// ```json
257    /// { "B": true }
258    /// ```
259    Bool(bool),
260    /// JSON representation:
261    /// ```json
262    /// { "U": "100" }
263    /// ```
264    ///
265    /// Numbers are encoded as JSON string to avoid losing precision when reading them in
266    /// Javascript/Typescript.
267    U64(u64),
268    /// JSON representation:
269    /// ```json
270    /// { "I": "-100" }
271    /// ```
272    I64(i64),
273    /// JSON representation:
274    /// ```json
275    /// { "F": "0.0" }
276    /// ```
277    /// Scientific notation is supported:
278    /// ```json
279    /// { "F": "1e9" }
280    /// ```
281    F64(f64),
282    /// [`rust_decimal::Decimal`], suitable for financial calculations.
283    ///
284    /// JSON representation:
285    /// ```json
286    /// { "D": "3.1415926535897932384626433832" }
287    /// ```
288    Decimal(Decimal),
289    /// JSON representation:
290    /// ```json
291    /// { "U1": "340282366920938463463374607431768211455" }
292    /// ```
293    U128(u128),
294    /// JSON representation:
295    /// ```json
296    /// { "I1": "-170141183460469231731687303715884105728" }
297    /// ```
298    I128(i128),
299    /// 32-bytes binary values, usually a Solana public key.
300    ///
301    /// JSON representation: encoded as a base-58 string
302    /// ```json
303    /// { "B3": "FMQUifdAHTytSxhiK4N7LmpvKRZaUmBnNnZmzFsdTPHB" }
304    /// ```
305    B32([u8; 32]),
306    /// 64-bytes binary values, usually a Solana signature or keypair.
307    ///
308    /// JSON representation: encoded as a base-58 string
309    /// ```json
310    /// { "B6": "4onDpbfeT7nNN9MNMvTEZRn6pbtrQc1pdTBJB4a7HbfhAE6c5bkbuuFfYtkqs99hAqp5o6j7W1VyuKDxCn79k3Tk" }
311    /// ```
312    B64([u8; 64]),
313    /// Binary values with length other than 32 and 64.
314    ///
315    /// JSON representation: encoded as a base-64 string
316    /// ```json
317    /// { "BY": "UmFpbnk=" }
318    /// ```
319    Bytes(bytes::Bytes),
320    /// An array of [`Value`]. Array can contains other arrays, maps, ect. Array elements do not
321    /// have to be of the same type.
322    ///
323    /// JSON representation:
324    ///
325    /// Example array containing a number and a string:
326    /// ```json
327    /// {
328    ///     "A": [
329    ///         { "U": 0 },
330    ///         { "S": "hello" }
331    ///     ]
332    /// }
333    /// ```
334    Array(Vec<Self>),
335    /// A key-value map, implemented with [`indexmap::IndexMap`], will preserve insertion order.
336    /// Keys are strings and values can be any [`Value`].
337    ///
338    /// JSON representation:
339    /// ```json
340    /// {
341    ///     "M": {
342    ///         "first name": { "S": "John" },
343    ///         "age": { "U": "20" }
344    ///     }
345    /// }
346    /// ```
347    Map(Map),
348}
349
350impl JsonSchema for Value {
351    fn schema_name() -> std::borrow::Cow<'static, str> {
352        "Value".into()
353    }
354
355    fn schema_id() -> std::borrow::Cow<'static, str> {
356        "https://schema.spaceoperator.com/value.schema.json".into()
357    }
358
359    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
360        serde_json::from_str(include_str!("../value.schema.json")).unwrap()
361    }
362}
363
364impl Value {
365    pub fn new_keypair_bs58(s: &str) -> Result<Self, Error> {
366        // and Ed25519 keypair
367        const KEYPAIR_LENGTH: usize = 64;
368        let mut buf = [0u8; KEYPAIR_LENGTH];
369        let size = bs58::decode(s).into(&mut buf)?;
370        if size != KEYPAIR_LENGTH {
371            return Err(Error::InvalidLenght {
372                need: KEYPAIR_LENGTH,
373                got: size,
374            });
375        }
376
377        Ok(Value::B64(buf))
378    }
379
380    pub fn normalize(self) -> Self {
381        match self {
382            Value::Null
383            | Value::String(_)
384            | Value::Bool(_)
385            | Value::U64(_)
386            | Value::I64(_)
387            | Value::F64(_)
388            | Value::B32(_)
389            | Value::B64(_)
390            | Value::Bytes(_) => self,
391            Value::Decimal(mut d) => {
392                d.normalize_assign();
393                if d.scale() == 0 {
394                    Value::I128(d.to_i128().expect("always fit into i128")).normalize()
395                } else {
396                    Value::Decimal(d)
397                }
398            }
399            Value::I128(i) => if i < 0 {
400                i64::try_from(i).map(Value::I64).ok()
401            } else {
402                u64::try_from(i).map(Value::U64).ok()
403            }
404            .unwrap_or(self),
405            Value::U128(u) => u64::try_from(u).map(Value::U64).unwrap_or(self),
406            Value::Array(mut a) => {
407                for v in &mut a {
408                    *v = std::mem::take(v).normalize();
409                }
410                Value::Array(a)
411            }
412            Value::Map(mut m) => {
413                for v in m.values_mut() {
414                    *v = std::mem::take(v).normalize();
415                }
416                Value::Map(m)
417            }
418        }
419    }
420}
421
422#[cfg(feature = "json")]
423mod json {
424    use crate::Value;
425    use rust_decimal::Decimal;
426
427    impl From<serde_json::Value> for Value {
428        fn from(value: serde_json::Value) -> Self {
429            match value {
430                serde_json::Value::Null => Value::Null,
431                serde_json::Value::Bool(b) => Value::Bool(b),
432                serde_json::Value::Number(n) => {
433                    if let Some(u) = n.as_u64() {
434                        Value::U64(u)
435                    } else if let Some(i) = n.as_i64() {
436                        if i < 0 {
437                            Value::I64(i)
438                        } else {
439                            Value::U64(i as u64)
440                        }
441                    } else {
442                        let s = n.to_string();
443                        if let Ok(u) = s.parse::<u128>() {
444                            Value::U128(u)
445                        } else if let Ok(i) = s.parse::<i128>() {
446                            Value::I128(i)
447                        } else if let Ok(d) = s.parse::<Decimal>() {
448                            Value::Decimal(d)
449                        } else if let Ok(d) = Decimal::from_scientific(&s) {
450                            Value::Decimal(d)
451                        } else if let Ok(f) = s.parse::<f64>() {
452                            Value::F64(f)
453                        } else {
454                            // unlikely to happen
455                            // if happen, probably a bug in serde_json
456                            Value::String(s)
457                        }
458                    }
459                }
460                serde_json::Value::String(s) => Value::String(s),
461                serde_json::Value::Array(vec) => {
462                    Value::Array(vec.into_iter().map(Value::from).collect())
463                }
464                serde_json::Value::Object(map) => {
465                    Value::Map(map.into_iter().map(|(k, v)| (k, Value::from(v))).collect())
466                }
467            }
468        }
469    }
470
471    impl From<Value> for serde_json::Value {
472        fn from(value: Value) -> Self {
473            match value {
474                Value::Null => serde_json::Value::Null,
475                Value::String(x) => x.into(),
476                Value::Bool(x) => x.into(),
477                Value::U64(x) => x.into(),
478                Value::I64(x) => x.into(),
479                Value::F64(x) => x.into(),
480                Value::Array(x) => x.into(),
481                Value::Map(x) => x
482                    .into_iter()
483                    .map(|(key, value)| (key, value.into()))
484                    .collect::<serde_json::Map<_, _>>()
485                    .into(),
486                Value::U128(value) => value
487                    .try_into()
488                    .map(u64::into)
489                    .unwrap_or_else(|_| (value as f64).into()),
490                Value::I128(value) => value
491                    .try_into()
492                    .map(i64::into)
493                    .unwrap_or_else(|_| (value as f64).into()),
494                Value::Decimal(mut d) => {
495                    d.normalize_assign();
496                    if d.scale() == 0 {
497                        if let Ok(n) = u64::try_from(d) {
498                            n.into()
499                        } else if let Ok(n) = i64::try_from(d) {
500                            n.into()
501                        } else {
502                            f64::try_from(d).map_or(serde_json::Value::Null, Into::into)
503                        }
504                    } else {
505                        f64::try_from(d).map_or(serde_json::Value::Null, Into::into)
506                    }
507                }
508                Value::B32(b) => (&b[..]).into(),
509                Value::B64(b) => (&b[..]).into(),
510                Value::Bytes(b) => (&b[..]).into(),
511            }
512        }
513    }
514}
515
516impl From<String> for Value {
517    fn from(x: String) -> Self {
518        Self::String(x)
519    }
520}
521
522impl From<&str> for Value {
523    fn from(x: &str) -> Self {
524        Self::String(x.to_owned())
525    }
526}
527
528impl From<bool> for Value {
529    fn from(x: bool) -> Self {
530        Self::Bool(x)
531    }
532}
533
534impl From<u8> for Value {
535    fn from(x: u8) -> Self {
536        Self::U64(x as u64)
537    }
538}
539
540impl From<u16> for Value {
541    fn from(x: u16) -> Self {
542        Self::U64(x as u64)
543    }
544}
545
546impl From<u32> for Value {
547    fn from(x: u32) -> Self {
548        Self::U64(x as u64)
549    }
550}
551
552impl From<u64> for Value {
553    fn from(x: u64) -> Self {
554        Self::U64(x)
555    }
556}
557
558impl From<u128> for Value {
559    fn from(x: u128) -> Self {
560        Self::U128(x)
561    }
562}
563
564impl From<i8> for Value {
565    fn from(x: i8) -> Self {
566        Self::I64(x as i64)
567    }
568}
569
570impl From<i16> for Value {
571    fn from(x: i16) -> Self {
572        Self::I64(x as i64)
573    }
574}
575
576impl From<i32> for Value {
577    fn from(x: i32) -> Self {
578        Self::I64(x as i64)
579    }
580}
581
582impl From<i64> for Value {
583    fn from(x: i64) -> Self {
584        Self::I64(x)
585    }
586}
587
588impl From<i128> for Value {
589    fn from(x: i128) -> Self {
590        Self::I128(x)
591    }
592}
593
594impl From<Decimal> for Value {
595    fn from(x: Decimal) -> Self {
596        Self::Decimal(x)
597    }
598}
599
600impl From<f32> for Value {
601    fn from(x: f32) -> Self {
602        Self::F64(x as f64)
603    }
604}
605
606impl From<f64> for Value {
607    fn from(x: f64) -> Self {
608        Self::F64(x)
609    }
610}
611
612impl From<[u8; 32]> for Value {
613    fn from(x: [u8; 32]) -> Self {
614        Self::B32(x)
615    }
616}
617
618impl From<[u8; 64]> for Value {
619    fn from(x: [u8; 64]) -> Self {
620        Self::B64(x)
621    }
622}
623
624#[cfg(feature = "solana-pubkey")]
625impl From<solana_pubkey::Pubkey> for Value {
626    fn from(x: solana_pubkey::Pubkey) -> Self {
627        Self::B32(x.to_bytes())
628    }
629}
630
631#[cfg(feature = "solana-keypair")]
632impl From<solana_keypair::Keypair> for Value {
633    fn from(x: solana_keypair::Keypair) -> Self {
634        Self::B64(x.to_bytes())
635    }
636}
637
638#[cfg(feature = "solana-signature")]
639impl From<solana_signature::Signature> for Value {
640    fn from(x: solana_signature::Signature) -> Self {
641        Self::B64(x.into())
642    }
643}
644
645impl From<bytes::Bytes> for Value {
646    fn from(x: bytes::Bytes) -> Self {
647        match x.len() {
648            32 => Self::B32(<_>::try_from(&*x).unwrap()),
649            64 => Self::B64(<_>::try_from(&*x).unwrap()),
650            _ => Self::Bytes(x),
651        }
652    }
653}
654
655impl From<&[u8]> for Value {
656    fn from(x: &[u8]) -> Self {
657        match x.len() {
658            32 => Self::B32(<_>::try_from(x).unwrap()),
659            64 => Self::B64(<_>::try_from(x).unwrap()),
660            _ => Self::Bytes(bytes::Bytes::copy_from_slice(x)),
661        }
662    }
663}
664
665impl From<Vec<u8>> for Value {
666    fn from(x: Vec<u8>) -> Self {
667        match x.len() {
668            32 => Self::B32(<_>::try_from(&*x).unwrap()),
669            64 => Self::B64(<_>::try_from(&*x).unwrap()),
670            _ => Self::Bytes(x.into()),
671        }
672    }
673}
674
675impl From<Vec<Value>> for Value {
676    fn from(x: Vec<Value>) -> Self {
677        Self::Array(x)
678    }
679}
680
681impl From<Map> for Value {
682    fn from(x: Map) -> Self {
683        Self::Map(x)
684    }
685}
686
687impl std::fmt::Debug for Value {
688    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
689        match self {
690            Value::Null => f.debug_tuple("Null").finish(),
691            Value::String(x) => f.debug_tuple("String").field(x).finish(),
692            Value::Bool(x) => f.debug_tuple("Bool").field(x).finish(),
693            Value::I64(x) => f.debug_tuple("I64").field(x).finish(),
694            Value::U64(x) => f.debug_tuple("U64").field(x).finish(),
695            Value::F64(x) => f.debug_tuple("F64").field(x).finish(),
696            Value::Decimal(x) => f.debug_tuple("Decimal").field(x).finish(),
697            Value::I128(x) => f.debug_tuple("I128").field(x).finish(),
698            Value::U128(x) => f.debug_tuple("U128").field(x).finish(),
699            Value::Array(x) => f.debug_tuple("Array").field(x).finish(),
700            Value::Map(x) => f.debug_tuple("Map").field(x).finish(),
701            Value::Bytes(x) => f.debug_tuple("Bytes").field(&x.len()).finish(),
702            Value::B32(x) => f
703                .debug_tuple("B32")
704                .field(&bs58::encode(x).into_string())
705                .finish(),
706            Value::B64(x) => f
707                .debug_tuple("B64")
708                .field(&bs58::encode(x).into_string())
709                .finish(),
710        }
711    }
712}
713
714#[derive(ThisError, Debug)]
715pub enum Error {
716    #[error("{0}")]
717    Custom(String),
718    #[error("key must be a string")]
719    KeyMustBeAString,
720    #[error("invalid base58: {0}")]
721    Bs58Decode(#[from] bs58::decode::Error),
722    #[error("need length {need}, got {got}")]
723    InvalidLenght { need: usize, got: usize },
724    #[error("expected a map")]
725    ExpectedMap,
726    #[error("expected array")]
727    ExpectedArray,
728}
729
730impl serde::ser::Error for Error {
731    fn custom<T>(msg: T) -> Self
732    where
733        T: std::fmt::Display,
734    {
735        Self::Custom(msg.to_string())
736    }
737}
738
739impl serde::de::Error for Error {
740    fn custom<T>(msg: T) -> Self
741    where
742        T: std::fmt::Display,
743    {
744        Self::Custom(msg.to_string())
745    }
746}
747
748// default implementation of [u8] doesn't call serialize_bytes
749pub struct Bytes<'a>(pub &'a [u8]);
750
751impl serde::Serialize for Bytes<'_> {
752    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
753    where
754        S: serde::Serializer,
755    {
756        s.serialize_bytes(self.0)
757    }
758}
759
760pub mod default {
761    pub const fn bool_true() -> bool {
762        true
763    }
764
765    pub const fn bool_false() -> bool {
766        false
767    }
768}
769
770pub(crate) struct OptionVisitor<V>(pub(crate) V);
771
772impl<'de, V> serde::de::Visitor<'de> for OptionVisitor<V>
773where
774    V: serde::de::Visitor<'de>,
775{
776    type Value = Option<V::Value>;
777
778    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
779        formatter.write_str("optional ")?;
780        self.0.expecting(formatter)
781    }
782
783    fn visit_none<E>(self) -> Result<Self::Value, E>
784    where
785        E: serde::de::Error,
786    {
787        Ok(None)
788    }
789
790    fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
791    where
792        D: serde::Deserializer<'de>,
793    {
794        d.deserialize_any(self.0).map(Some)
795    }
796}
797
798#[cfg(test)]
799mod tests {
800    use super::*;
801    use rust_decimal_macros::dec;
802
803    #[test]
804    fn test_solana_instruction() {
805        use solana_instruction::{AccountMeta, Instruction};
806        use solana_pubkey::pubkey;
807
808        let i = Instruction::new_with_bytes(
809            pubkey!("ESxeViFP4r7THzVx9hJDkhj4HrNGSjJSFRPbGaAb97hN"),
810            &[100; 1024],
811            vec![AccountMeta {
812                pubkey: pubkey!("ESxeViFP4r7THzVx9hJDkhj4HrNGSjJSFRPbGaAb97hN"),
813                is_signer: true,
814                is_writable: false,
815            }],
816        );
817
818        let v = to_value(&i).unwrap();
819        dbg!(&v);
820
821        let i1: Instruction = from_value(v).unwrap();
822
823        assert_eq!(i, i1);
824    }
825
826    #[test]
827    fn test_json() {
828        fn t(v: Value, s: &str) {
829            assert_eq!(s, serde_json::to_string(&v).unwrap());
830            assert_eq!(v, serde_json::from_str::<Value>(s).unwrap());
831        }
832        t(Value::Null, r#"{"N":0}"#);
833        t(Value::String("hello".to_owned()), r#"{"S":"hello"}"#);
834        t(Value::U64(0), r#"{"U":"0"}"#);
835        t(Value::I64(-1), r#"{"I":"-1"}"#);
836        t(
837            Value::U128(u128::MAX),
838            r#"{"U1":"340282366920938463463374607431768211455"}"#,
839        );
840        t(
841            Value::I128(i128::MIN),
842            r#"{"I1":"-170141183460469231731687303715884105728"}"#,
843        );
844        t(Value::Bool(true), r#"{"B":true}"#);
845        t(
846            Value::Decimal(dec!(3.1415926535897932384626433833)),
847            r#"{"D":"3.1415926535897932384626433833"}"#,
848        );
849        t(
850            crate::map! {
851                "foo" => 1i64,
852            }
853            .into(),
854            r#"{"M":{"foo":{"I":"1"}}}"#,
855        );
856        t(
857            Value::Array(vec![1i64.into(), "hello".into()]),
858            r#"{"A":[{"I":"1"},{"S":"hello"}]}"#,
859        );
860        t(
861            Value::B32(
862                bs58::decode("5sNRWMrT2P3KULzW3faaktCB3k2eqHow2GBJtcsCPcg7")
863                    .into_vec()
864                    .unwrap()
865                    .try_into()
866                    .unwrap(),
867            ),
868            r#"{"B3":"5sNRWMrT2P3KULzW3faaktCB3k2eqHow2GBJtcsCPcg7"}"#,
869        );
870        t(
871            Value::B64(
872                bs58::decode("3PvNxykqBz1BzBaq2AMU4Sa3CPJGnSC9JXkyzXe33m6W7Sj4MMgsZet6YxUQdPx1fEFU79QWm6RpPRVJAyeqiNsR")
873                    .into_vec()
874                    .unwrap()
875                    .try_into()
876                    .unwrap(),
877            ),
878            r#"{"B6":"3PvNxykqBz1BzBaq2AMU4Sa3CPJGnSC9JXkyzXe33m6W7Sj4MMgsZet6YxUQdPx1fEFU79QWm6RpPRVJAyeqiNsR"}"#,
879        );
880        t(
881            Value::Bytes(bytes::Bytes::from_static(&[
882                104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100,
883            ])),
884            r#"{"BY":"aGVsbG8gd29ybGQ="}"#,
885        );
886    }
887
888    #[test]
889    fn test_array_ser() {
890        #[derive(serde::Serialize)]
891        struct Output {
892            value: Value,
893        }
894
895        let mut v = crate::to_map(&Output {
896            value: Vec::from([Value::U64(1)]).into(),
897        })
898        .unwrap();
899        assert_eq!(
900            v.swap_remove("value").unwrap(),
901            Value::Array([1u64.into()].into())
902        )
903    }
904
905    #[cfg(feature = "json")]
906    #[test]
907    fn test_number_into_json() {
908        let json: serde_json::Value = Value::Decimal(dec!(15966.2)).into();
909        assert_eq!(json.as_f64().unwrap(), 15966.2);
910    }
911}