arcis_interface/
json.rs

1use crate::types::{CircuitInterface, ScalarKind, Value};
2use serde::{
3    de::{self, MapAccess, Visitor},
4    Deserialize,
5    Deserializer,
6    Serialize,
7};
8use serde_json::{json, Value as JsonValue};
9use std::fmt;
10
11#[derive(Serialize, Deserialize, Debug)]
12pub struct ManticoreInterface {
13    pub inputs: Vec<String>,
14    pub outputs: Vec<String>,
15}
16
17impl ManticoreInterface {
18    pub fn new(inputs: Vec<String>, outputs: Vec<String>) -> Self {
19        Self { inputs, outputs }
20    }
21
22    pub fn serialize(&self) -> Result<String, serde_json::Error> {
23        serde_json::to_string(self)
24    }
25
26    pub fn from_json(input: &str) -> Result<Self, serde_json::Error> {
27        serde_json::from_str(input)
28    }
29}
30
31impl<'de> Deserialize<'de> for CircuitInterface {
32    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
33    where
34        D: Deserializer<'de>,
35    {
36        enum Field {
37            Name,
38            Inputs,
39            Outputs,
40        }
41
42        impl<'de> Deserialize<'de> for Field {
43            fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
44            where
45                D: Deserializer<'de>,
46            {
47                struct FieldVisitor;
48
49                impl Visitor<'_> for FieldVisitor {
50                    type Value = Field;
51
52                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53                        formatter.write_str("`name`, `inputs`, or `outputs`")
54                    }
55
56                    fn visit_str<E>(self, value: &str) -> Result<Field, E>
57                    where
58                        E: de::Error,
59                    {
60                        match value {
61                            "name" => Ok(Field::Name),
62                            "inputs" => Ok(Field::Inputs),
63                            "outputs" => Ok(Field::Outputs),
64                            _ => Err(de::Error::unknown_field(value, FIELDS)),
65                        }
66                    }
67                }
68
69                deserializer.deserialize_identifier(FieldVisitor)
70            }
71        }
72
73        struct CircuitInterfaceVisitor;
74
75        impl<'de> Visitor<'de> for CircuitInterfaceVisitor {
76            type Value = CircuitInterface;
77
78            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
79                formatter.write_str("struct CircuitInterface")
80            }
81
82            fn visit_map<V>(self, mut map: V) -> Result<CircuitInterface, V::Error>
83            where
84                V: MapAccess<'de>,
85            {
86                let mut name = None;
87                let mut inputs = None;
88                let mut outputs = None;
89
90                while let Some(key) = map.next_key()? {
91                    match key {
92                        Field::Name => {
93                            if name.is_some() {
94                                return Err(de::Error::duplicate_field("name"));
95                            }
96                            name = Some(map.next_value()?);
97                        }
98                        Field::Inputs => {
99                            if inputs.is_some() {
100                                return Err(de::Error::duplicate_field("inputs"));
101                            }
102                            inputs = Some(map.next_value()?);
103                        }
104                        Field::Outputs => {
105                            if outputs.is_some() {
106                                return Err(de::Error::duplicate_field("outputs"));
107                            }
108                            outputs = Some(map.next_value()?);
109                        }
110                    }
111                }
112
113                let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
114                let inputs = inputs.ok_or_else(|| de::Error::missing_field("inputs"))?;
115                let outputs = outputs.ok_or_else(|| de::Error::missing_field("output"))?;
116
117                Ok(CircuitInterface {
118                    name,
119                    inputs,
120                    outputs,
121                })
122            }
123        }
124
125        const FIELDS: &[&str] = &["name", "inputs", "outputs"];
126        deserializer.deserialize_struct("CircuitInterface", FIELDS, CircuitInterfaceVisitor)
127    }
128}
129
130impl Value {
131    /// Maps scalar size and kind to JSON type name.
132    ///
133    /// Returns standard Rust type names for common sizes (e.g., "u32", "i64"),
134    /// or generic names for non-standard sizes ("scalar" for unsigned, "signed_integer" for
135    /// signed).
136    fn get_scalar_type_name(size_in_bits: usize, kind: ScalarKind) -> &'static str {
137        match kind {
138            ScalarKind::Unsigned => match size_in_bits {
139                8 => "u8",
140                16 => "u16",
141                32 => "u32",
142                64 => "u64",
143                128 => "u128",
144                _ => "scalar",
145            },
146            ScalarKind::Signed => match size_in_bits {
147                8 => "i8",
148                16 => "i16",
149                32 => "i32",
150                64 => "i64",
151                128 => "i128",
152                _ => "signed_integer",
153            },
154        }
155    }
156}
157
158impl Serialize for Value {
159    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
160    where
161        S: serde::Serializer,
162    {
163        let json_value = match self {
164            Value::MScalar { size_in_bits } => json!({
165                "type": "mscalar",
166                "size_in_bits": size_in_bits
167            }),
168            Value::MFloat { size_in_bits } => json!({
169                "type": "mfloat",
170                "size_in_bits": size_in_bits
171            }),
172            Value::MBool => json!({
173                "type": "mbool"
174            }),
175            Value::Scalar { size_in_bits, kind } => json!({
176                "type": Value::get_scalar_type_name(*size_in_bits, *kind),
177                "size_in_bits": size_in_bits
178            }),
179            Value::Float { size_in_bits } => json!({
180                "type": "float",
181                "size_in_bits": size_in_bits
182            }),
183            Value::Bool => json!({
184                "type": "bool"
185            }),
186            Value::Ciphertext { size_in_bits } => json!({
187                "type": "ciphertext",
188                "size_in_bits": size_in_bits
189            }),
190            Value::ArcisX25519Pubkey => json!({
191                "type": "arcis_x25519_pubkey",
192            }),
193            Value::Point => json!({
194                "type": "point"
195            }),
196            Value::Array(vec) => json!({
197                "type": "array",
198                "content": vec
199            }),
200            Value::Tuple(vec) => json!({
201                "type": "tuple",
202                "content": vec
203            }),
204            Value::Struct(vec) => json!({
205                "type": "struct",
206                "content": vec
207            }),
208        };
209        json_value.serialize(serializer)
210    }
211}
212
213impl<'de> Deserialize<'de> for Value {
214    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215    where
216        D: serde::Deserializer<'de>,
217    {
218        let json_value = JsonValue::deserialize(deserializer)?;
219
220        match json_value {
221            JsonValue::Object(map) => {
222                let type_ = map
223                    .get("type")
224                    .and_then(JsonValue::as_str)
225                    .ok_or_else(|| serde::de::Error::missing_field("type"))?;
226
227                match type_ {
228                    "mscalar" => {
229                        let size_in_bits = map
230                            .get("size_in_bits")
231                            .and_then(JsonValue::as_u64)
232                            .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
233                        Ok(Value::MScalar {
234                            size_in_bits: size_in_bits as usize,
235                        })
236                    }
237                    "mfloat" => {
238                        let size_in_bits = map
239                            .get("size_in_bits")
240                            .and_then(JsonValue::as_u64)
241                            .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
242                        Ok(Value::MFloat {
243                            size_in_bits: size_in_bits as usize,
244                        })
245                    }
246                    "mbool" => Ok(Value::MBool),
247                    "u8" => Ok(Value::Scalar {
248                        size_in_bits: 8,
249                        kind: ScalarKind::Unsigned,
250                    }),
251                    "u16" => Ok(Value::Scalar {
252                        size_in_bits: 16,
253                        kind: ScalarKind::Unsigned,
254                    }),
255                    "u32" => Ok(Value::Scalar {
256                        size_in_bits: 32,
257                        kind: ScalarKind::Unsigned,
258                    }),
259                    "u64" => Ok(Value::Scalar {
260                        size_in_bits: 64,
261                        kind: ScalarKind::Unsigned,
262                    }),
263                    "u128" => Ok(Value::Scalar {
264                        size_in_bits: 128,
265                        kind: ScalarKind::Unsigned,
266                    }),
267                    "i8" => Ok(Value::Scalar {
268                        size_in_bits: 8,
269                        kind: ScalarKind::Signed,
270                    }),
271                    "i16" => Ok(Value::Scalar {
272                        size_in_bits: 16,
273                        kind: ScalarKind::Signed,
274                    }),
275                    "i32" => Ok(Value::Scalar {
276                        size_in_bits: 32,
277                        kind: ScalarKind::Signed,
278                    }),
279                    "i64" => Ok(Value::Scalar {
280                        size_in_bits: 64,
281                        kind: ScalarKind::Signed,
282                    }),
283                    "i128" => Ok(Value::Scalar {
284                        size_in_bits: 128,
285                        kind: ScalarKind::Signed,
286                    }),
287                    "scalar" => {
288                        let size_in_bits = map
289                            .get("size_in_bits")
290                            .and_then(JsonValue::as_u64)
291                            .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
292                        Ok(Value::Scalar {
293                            size_in_bits: size_in_bits as usize,
294                            kind: ScalarKind::Unsigned,
295                        })
296                    }
297                    "signed_integer" => {
298                        let size_in_bits = map
299                            .get("size_in_bits")
300                            .and_then(JsonValue::as_u64)
301                            .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
302                        Ok(Value::Scalar {
303                            size_in_bits: size_in_bits as usize,
304                            kind: ScalarKind::Signed,
305                        })
306                    }
307                    "ciphertext" => {
308                        let size_in_bits = map
309                            .get("size_in_bits")
310                            .and_then(JsonValue::as_u64)
311                            .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
312                        Ok(Value::Ciphertext {
313                            size_in_bits: size_in_bits as usize,
314                        })
315                    }
316                    "arcis_x25519_pubkey" => Ok(Value::ArcisX25519Pubkey),
317                    "float" => {
318                        let size_in_bits = map
319                            .get("size_in_bits")
320                            .and_then(JsonValue::as_u64)
321                            .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
322                        Ok(Value::Float {
323                            size_in_bits: size_in_bits as usize,
324                        })
325                    }
326                    "bool" => Ok(Value::Bool),
327                    "array" | "tuple" | "struct" => {
328                        let content = map
329                            .get("content")
330                            .ok_or_else(|| serde::de::Error::missing_field("content"))?;
331                        let vec: Vec<Value> =
332                            serde_json::from_value(content.clone()).map_err(|e| {
333                                serde::de::Error::custom(format!(
334                                    "Failed to deserialize content: {}",
335                                    e
336                                ))
337                            })?;
338                        match type_ {
339                            "array" => Ok(Value::Array(vec)),
340                            "tuple" => Ok(Value::Tuple(vec)),
341                            "struct" => Ok(Value::Struct(vec)),
342                            _ => unreachable!(),
343                        }
344                    }
345                    _ => Err(serde::de::Error::unknown_variant(
346                        type_,
347                        &[
348                            "mscalar",
349                            "mfloat",
350                            "mbool",
351                            "u8",
352                            "u16",
353                            "u32",
354                            "u64",
355                            "u128",
356                            "i8",
357                            "i16",
358                            "i32",
359                            "i64",
360                            "i128",
361                            "scalar",
362                            "signed_integer",
363                            "float",
364                            "bool",
365                            "array",
366                            "tuple",
367                            "struct",
368                            "ciphertext",
369                            "arcis_x25519_pubkey",
370                        ],
371                    )),
372                }
373            }
374            _ => Err(serde::de::Error::invalid_type(
375                serde::de::Unexpected::Other("non-object"),
376                &"object",
377            )),
378        }
379    }
380}
381
382#[cfg(test)]
383mod tests {
384    use super::*;
385    use serde_json::json;
386
387    #[test]
388    fn test_mscalar_serialization() {
389        let value = Value::MScalar { size_in_bits: 32 };
390        let serialized = serde_json::to_value(value).unwrap();
391        assert_eq!(
392            serialized,
393            json!({
394                "type": "mscalar",
395                "size_in_bits": 32
396            })
397        );
398    }
399
400    #[test]
401    fn test_mbool_serialization() {
402        let value = Value::MBool;
403        let serialized = serde_json::to_value(value).unwrap();
404        assert_eq!(
405            serialized,
406            json!({
407                "type": "mbool"
408            })
409        );
410    }
411
412    #[test]
413    fn test_bool_serialization() {
414        let value = Value::Bool;
415        let serialized = serde_json::to_value(value).unwrap();
416        assert_eq!(
417            serialized,
418            json!({
419                "type": "bool"
420            })
421        );
422    }
423
424    #[test]
425    fn test_array_serialization() {
426        let value = Value::Array(vec![
427            Value::Scalar {
428                size_in_bits: 60,
429                kind: ScalarKind::Unsigned,
430            },
431            Value::Bool,
432        ]);
433        let serialized = serde_json::to_value(value).unwrap();
434        assert_eq!(
435            serialized,
436            json!({
437                "type": "array",
438                "content": [
439                    {
440                        "type": "scalar",
441                        "size_in_bits": 60
442                    },
443                    {
444                        "type": "bool"
445                    }
446                ]
447            })
448        );
449    }
450
451    #[test]
452    fn test_nested_structure_serialization() {
453        let value = Value::Struct(vec![
454            Value::Tuple(vec![Value::MScalar { size_in_bits: 32 }, Value::MBool]),
455            Value::Array(vec![
456                Value::Scalar {
457                    size_in_bits: 64,
458                    kind: ScalarKind::Unsigned,
459                },
460                Value::Bool,
461            ]),
462        ]);
463        let serialized = serde_json::to_string(&value).unwrap();
464        let deserialized: Value = serde_json::from_str(&serialized).unwrap();
465        assert_eq!(value, deserialized);
466    }
467
468    #[test]
469    fn test_mscalar_deserialization() {
470        let json = r#"{"type": "mscalar", "size_in_bits": 32}"#;
471        let deserialized: Value = serde_json::from_str(json).unwrap();
472        assert_eq!(deserialized, Value::MScalar { size_in_bits: 32 });
473    }
474
475    #[test]
476    fn test_array_deserialization() {
477        let json = r#"
478        {
479            "type": "array",
480            "content": [
481                {"type": "scalar", "size_in_bits": 64},
482                {"type": "bool"}
483            ]
484        }"#;
485        let deserialized: Value = serde_json::from_str(json).unwrap();
486        assert_eq!(
487            deserialized,
488            Value::Array(vec![
489                Value::Scalar {
490                    size_in_bits: 64,
491                    kind: ScalarKind::Unsigned,
492                },
493                Value::Bool,
494            ])
495        );
496    }
497
498    #[test]
499    fn test_invalid_type_deserialization() {
500        let json = r#"{"type": "invalid_type"}"#;
501        let result: Result<Value, _> = serde_json::from_str(json);
502        assert!(result.is_err());
503    }
504
505    #[test]
506    fn test_missing_size_in_bits_deserialization() {
507        let json = r#"{"type": "mscalar"}"#;
508        let result: Result<Value, _> = serde_json::from_str(json);
509        assert!(result.is_err());
510    }
511
512    #[test]
513    fn test_plaintext_type_serialization() {
514        // Test all standard numeric sizes (unsigned)
515        let test_cases = [
516            (
517                Value::Scalar {
518                    size_in_bits: 8,
519                    kind: ScalarKind::Unsigned,
520                },
521                "u8",
522            ),
523            (
524                Value::Scalar {
525                    size_in_bits: 16,
526                    kind: ScalarKind::Unsigned,
527                },
528                "u16",
529            ),
530            (
531                Value::Scalar {
532                    size_in_bits: 32,
533                    kind: ScalarKind::Unsigned,
534                },
535                "u32",
536            ),
537            (
538                Value::Scalar {
539                    size_in_bits: 64,
540                    kind: ScalarKind::Unsigned,
541                },
542                "u64",
543            ),
544            (
545                Value::Scalar {
546                    size_in_bits: 128,
547                    kind: ScalarKind::Unsigned,
548                },
549                "u128",
550            ),
551            // Test non-standard size falls back to scalar
552            (
553                Value::Scalar {
554                    size_in_bits: 24,
555                    kind: ScalarKind::Unsigned,
556                },
557                "scalar",
558            ),
559        ];
560
561        for (value, expected_type) in test_cases {
562            // Test serialization
563            let serialized = serde_json::to_value(&value).unwrap();
564            let expected = match &value {
565                Value::Scalar { size_in_bits, .. } => json!({
566                    "type": expected_type,
567                    "size_in_bits": size_in_bits
568                }),
569                Value::Bool => json!({
570                    "type": expected_type
571                }),
572                _ => unreachable!(),
573            };
574            assert_eq!(serialized, expected);
575
576            // Test deserialization
577            let json = serde_json::to_string(&expected).unwrap();
578            let deserialized: Value = serde_json::from_str(&json).unwrap();
579            assert_eq!(deserialized, value);
580        }
581    }
582
583    #[test]
584    fn test_signed_integer_serialization() {
585        let test_cases = [
586            (
587                Value::Scalar {
588                    size_in_bits: 8,
589                    kind: ScalarKind::Signed,
590                },
591                "i8",
592            ),
593            (
594                Value::Scalar {
595                    size_in_bits: 16,
596                    kind: ScalarKind::Signed,
597                },
598                "i16",
599            ),
600            (
601                Value::Scalar {
602                    size_in_bits: 32,
603                    kind: ScalarKind::Signed,
604                },
605                "i32",
606            ),
607            (
608                Value::Scalar {
609                    size_in_bits: 64,
610                    kind: ScalarKind::Signed,
611                },
612                "i64",
613            ),
614            (
615                Value::Scalar {
616                    size_in_bits: 128,
617                    kind: ScalarKind::Signed,
618                },
619                "i128",
620            ),
621            (
622                Value::Scalar {
623                    size_in_bits: 24,
624                    kind: ScalarKind::Signed,
625                },
626                "signed_integer",
627            ),
628        ];
629
630        for (value, expected_type) in test_cases {
631            // Test serialization
632            let serialized = serde_json::to_value(&value).unwrap();
633            let expected = json!({
634                "type": expected_type,
635                "size_in_bits": match &value {
636                    Value::Scalar { size_in_bits, .. } => size_in_bits,
637                    _ => unreachable!(),
638                }
639            });
640            assert_eq!(serialized, expected);
641
642            // Test deserialization
643            let json = serde_json::to_string(&expected).unwrap();
644            let deserialized: Value = serde_json::from_str(&json).unwrap();
645            assert_eq!(deserialized, value);
646        }
647    }
648
649    #[test]
650    fn test_backward_compatibility() {
651        // Test that old JSON without 'kind' field defaults to unsigned
652        let old_json_cases = [
653            (r#"{"type": "u8", "size_in_bits": 8}"#, 8),
654            (r#"{"type": "u16", "size_in_bits": 16}"#, 16),
655            (r#"{"type": "u32", "size_in_bits": 32}"#, 32),
656            (r#"{"type": "u64", "size_in_bits": 64}"#, 64),
657            (r#"{"type": "u128", "size_in_bits": 128}"#, 128),
658            (r#"{"type": "scalar", "size_in_bits": 24}"#, 24),
659        ];
660
661        for (json, expected_size) in old_json_cases {
662            let deserialized: Value = serde_json::from_str(json).unwrap();
663            assert_eq!(
664                deserialized,
665                Value::Scalar {
666                    size_in_bits: expected_size,
667                    kind: ScalarKind::Unsigned
668                }
669            );
670        }
671    }
672
673    #[test]
674    fn test_mixed_signed_unsigned_serialization() {
675        // Test that signed and unsigned integers serialize differently
676        let unsigned = Value::Scalar {
677            size_in_bits: 32,
678            kind: ScalarKind::Unsigned,
679        };
680        let signed = Value::Scalar {
681            size_in_bits: 32,
682            kind: ScalarKind::Signed,
683        };
684
685        let unsigned_json = serde_json::to_value(&unsigned).unwrap();
686        let signed_json = serde_json::to_value(&signed).unwrap();
687
688        assert_eq!(
689            unsigned_json,
690            json!({
691                "type": "u32",
692                "size_in_bits": 32
693            })
694        );
695        assert_eq!(
696            signed_json,
697            json!({
698                "type": "i32",
699                "size_in_bits": 32
700            })
701        );
702
703        // Ensure they're different
704        assert_ne!(unsigned_json, signed_json);
705    }
706}