bittensor_core/codec/
value.rs1#![allow(clippy::arithmetic_side_effects, clippy::indexing_slicing)]
7
8use std::fmt;
9
10#[derive(Debug, Clone, PartialEq)]
12pub enum Value {
13 Null,
15 Bool(bool),
16 Int(i128),
18 Uint(u128),
20 U256([u8; 32]),
22 Str(String),
23 Bytes(Vec<u8>),
26 List(Vec<Value>),
28 Tuple(Vec<Value>),
30 Dict(Vec<(Value, Value)>),
33}
34
35impl Value {
36 pub fn str(s: impl Into<String>) -> Self {
37 Value::Str(s.into())
38 }
39
40 pub fn hex(data: &[u8]) -> Self {
41 Value::Str(format!("0x{}", hex::encode(data)))
42 }
43
44 pub fn record(fields: Vec<(String, Value)>) -> Self {
46 Value::Dict(
47 fields
48 .into_iter()
49 .map(|(k, v)| (Value::Str(k), v))
50 .collect(),
51 )
52 }
53}
54
55pub fn to_corpus_json(value: &Value) -> serde_json::Value {
59 use serde_json::json;
60 match value {
61 Value::Null => serde_json::Value::Null,
62 Value::Bool(b) => json!(b),
63 Value::Int(i) => serde_json::Value::Number(
64 serde_json::Number::from_i128(*i).unwrap_or_else(|| serde_json::Number::from(0)),
65 ),
66 Value::Uint(u) => serde_json::Value::Number(
67 serde_json::Number::from_u128(*u).unwrap_or_else(|| serde_json::Number::from(0)),
68 ),
69 Value::U256(le) => {
70 let number = u256_decimal(le)
74 .parse::<serde_json::Number>()
75 .unwrap_or_else(|_| serde_json::Number::from(0));
76 serde_json::Value::Number(number)
77 }
78 Value::Str(s) => json!(s),
79 Value::Bytes(b) => json!(format!("0x{}", hex::encode(b))),
80 Value::List(items) | Value::Tuple(items) => {
81 serde_json::Value::Array(items.iter().map(to_corpus_json).collect())
82 }
83 Value::Dict(entries) => {
84 let mut map = serde_json::Map::new();
85 for (k, v) in entries {
86 map.insert(corpus_key(k), to_corpus_json(v));
87 }
88 serde_json::Value::Object(map)
89 }
90 }
91}
92
93fn corpus_key(key: &Value) -> String {
95 match key {
96 Value::Str(s) => s.clone(),
97 Value::Int(i) => i.to_string(),
98 Value::Uint(u) => u.to_string(),
99 Value::Bool(b) => (if *b { "True" } else { "False" }).to_string(),
100 other => format!("{other:?}"),
101 }
102}
103
104pub fn u256_decimal(le: &[u8; 32]) -> String {
106 let mut limbs: Vec<u8> = le.iter().rev().copied().collect(); let mut digits = Vec::new();
110 while limbs.iter().any(|&b| b != 0) {
111 let mut remainder: u32 = 0;
112 for byte in limbs.iter_mut() {
113 let value = (remainder << 8) | u32::from(*byte);
114 *byte = (value / 10) as u8;
115 remainder = value % 10;
116 }
117 digits.push(char::from(b'0' + remainder as u8));
118 }
119 if digits.is_empty() {
120 return "0".to_string();
121 }
122 digits.iter().rev().collect()
123}
124
125impl fmt::Display for Value {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 write!(f, "{}", to_corpus_json(self))
128 }
129}