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 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::UnsynchronizedBools { count } => json!({
197 "type": "unsynchronized_bools",
198 "count": count
199 }),
200 Value::Array(vec) => json!({
201 "type": "array",
202 "content": vec
203 }),
204 Value::Tuple(vec) => json!({
205 "type": "tuple",
206 "content": vec
207 }),
208 Value::Struct(vec) => json!({
209 "type": "struct",
210 "content": vec
211 }),
212 };
213 json_value.serialize(serializer)
214 }
215}
216
217impl<'de> Deserialize<'de> for Value {
218 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
219 where
220 D: serde::Deserializer<'de>,
221 {
222 let json_value = JsonValue::deserialize(deserializer)?;
223
224 match json_value {
225 JsonValue::Object(map) => {
226 let type_ = map
227 .get("type")
228 .and_then(JsonValue::as_str)
229 .ok_or_else(|| serde::de::Error::missing_field("type"))?;
230
231 match type_ {
232 "mscalar" => {
233 let size_in_bits = map
234 .get("size_in_bits")
235 .and_then(JsonValue::as_u64)
236 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
237 Ok(Value::MScalar {
238 size_in_bits: size_in_bits as usize,
239 })
240 }
241 "mfloat" => {
242 let size_in_bits = map
243 .get("size_in_bits")
244 .and_then(JsonValue::as_u64)
245 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
246 Ok(Value::MFloat {
247 size_in_bits: size_in_bits as usize,
248 })
249 }
250 "mbool" => Ok(Value::MBool),
251 "u8" => Ok(Value::Scalar {
252 size_in_bits: 8,
253 kind: ScalarKind::Unsigned,
254 }),
255 "u16" => Ok(Value::Scalar {
256 size_in_bits: 16,
257 kind: ScalarKind::Unsigned,
258 }),
259 "u32" => Ok(Value::Scalar {
260 size_in_bits: 32,
261 kind: ScalarKind::Unsigned,
262 }),
263 "u64" => Ok(Value::Scalar {
264 size_in_bits: 64,
265 kind: ScalarKind::Unsigned,
266 }),
267 "u128" => Ok(Value::Scalar {
268 size_in_bits: 128,
269 kind: ScalarKind::Unsigned,
270 }),
271 "i8" => Ok(Value::Scalar {
272 size_in_bits: 8,
273 kind: ScalarKind::Signed,
274 }),
275 "i16" => Ok(Value::Scalar {
276 size_in_bits: 16,
277 kind: ScalarKind::Signed,
278 }),
279 "i32" => Ok(Value::Scalar {
280 size_in_bits: 32,
281 kind: ScalarKind::Signed,
282 }),
283 "i64" => Ok(Value::Scalar {
284 size_in_bits: 64,
285 kind: ScalarKind::Signed,
286 }),
287 "i128" => Ok(Value::Scalar {
288 size_in_bits: 128,
289 kind: ScalarKind::Signed,
290 }),
291 "scalar" => {
292 let size_in_bits = map
293 .get("size_in_bits")
294 .and_then(JsonValue::as_u64)
295 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
296 Ok(Value::Scalar {
297 size_in_bits: size_in_bits as usize,
298 kind: ScalarKind::Unsigned,
299 })
300 }
301 "signed_integer" => {
302 let size_in_bits = map
303 .get("size_in_bits")
304 .and_then(JsonValue::as_u64)
305 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
306 Ok(Value::Scalar {
307 size_in_bits: size_in_bits as usize,
308 kind: ScalarKind::Signed,
309 })
310 }
311 "ciphertext" => {
312 let size_in_bits = map
313 .get("size_in_bits")
314 .and_then(JsonValue::as_u64)
315 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
316 Ok(Value::Ciphertext {
317 size_in_bits: size_in_bits as usize,
318 })
319 }
320 "arcis_x25519_pubkey" => Ok(Value::ArcisX25519Pubkey),
321 "point" => Ok(Value::Point),
322 "unsynchronized_bools" => {
323 let count = map
324 .get("count")
325 .and_then(JsonValue::as_u64)
326 .ok_or_else(|| serde::de::Error::missing_field("count"))?;
327 Ok(Value::UnsynchronizedBools {
328 count: count as usize,
329 })
330 }
331 "float" => {
332 let size_in_bits = map
333 .get("size_in_bits")
334 .and_then(JsonValue::as_u64)
335 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
336 Ok(Value::Float {
337 size_in_bits: size_in_bits as usize,
338 })
339 }
340 "bool" => Ok(Value::Bool),
341 "array" | "tuple" | "struct" => {
342 let content = map
343 .get("content")
344 .ok_or_else(|| serde::de::Error::missing_field("content"))?;
345 let vec: Vec<Value> =
346 serde_json::from_value(content.clone()).map_err(|e| {
347 serde::de::Error::custom(format!(
348 "Failed to deserialize content: {}",
349 e
350 ))
351 })?;
352 match type_ {
353 "array" => Ok(Value::Array(vec)),
354 "tuple" => Ok(Value::Tuple(vec)),
355 "struct" => Ok(Value::Struct(vec)),
356 _ => unreachable!(),
357 }
358 }
359 _ => Err(serde::de::Error::unknown_variant(
360 type_,
361 &[
362 "mscalar",
363 "mfloat",
364 "mbool",
365 "u8",
366 "u16",
367 "u32",
368 "u64",
369 "u128",
370 "i8",
371 "i16",
372 "i32",
373 "i64",
374 "i128",
375 "scalar",
376 "signed_integer",
377 "float",
378 "bool",
379 "array",
380 "tuple",
381 "struct",
382 "ciphertext",
383 "arcis_x25519_pubkey",
384 "point",
385 ],
386 )),
387 }
388 }
389 _ => Err(serde::de::Error::invalid_type(
390 serde::de::Unexpected::Other("non-object"),
391 &"object",
392 )),
393 }
394 }
395}
396
397#[cfg(test)]
398mod tests {
399 use super::*;
400 use serde_json::json;
401
402 #[test]
403 fn test_mscalar_serialization() {
404 let value = Value::MScalar { size_in_bits: 32 };
405 let serialized = serde_json::to_value(value).unwrap();
406 assert_eq!(
407 serialized,
408 json!({
409 "type": "mscalar",
410 "size_in_bits": 32
411 })
412 );
413 }
414
415 #[test]
416 fn test_unsynchronized_bools_round_trips() {
417 let value = Value::UnsynchronizedBools { count: 1568 };
418 let serialized = serde_json::to_value(value.clone()).unwrap();
419 assert_eq!(
420 serialized,
421 json!({
422 "type": "unsynchronized_bools",
423 "count": 1568
424 })
425 );
426 assert_eq!(serde_json::from_value::<Value>(serialized).unwrap(), value);
427 }
428
429 #[test]
432 fn test_unsynchronized_bools_is_one_value() {
433 assert_eq!(
434 Value::UnsynchronizedBools { count: 1568 }.size_in_scalars(),
435 1
436 );
437 }
438
439 #[test]
440 fn test_mbool_serialization() {
441 let value = Value::MBool;
442 let serialized = serde_json::to_value(value).unwrap();
443 assert_eq!(
444 serialized,
445 json!({
446 "type": "mbool"
447 })
448 );
449 }
450
451 #[test]
452 fn test_bool_serialization() {
453 let value = Value::Bool;
454 let serialized = serde_json::to_value(value).unwrap();
455 assert_eq!(
456 serialized,
457 json!({
458 "type": "bool"
459 })
460 );
461 }
462
463 #[test]
464 fn test_array_serialization() {
465 let value = Value::Array(vec![
466 Value::Scalar {
467 size_in_bits: 60,
468 kind: ScalarKind::Unsigned,
469 },
470 Value::Bool,
471 ]);
472 let serialized = serde_json::to_value(value).unwrap();
473 assert_eq!(
474 serialized,
475 json!({
476 "type": "array",
477 "content": [
478 {
479 "type": "scalar",
480 "size_in_bits": 60
481 },
482 {
483 "type": "bool"
484 }
485 ]
486 })
487 );
488 }
489
490 #[test]
491 fn test_nested_structure_serialization() {
492 let value = Value::Struct(vec![
493 Value::Tuple(vec![Value::MScalar { size_in_bits: 32 }, Value::MBool]),
494 Value::Array(vec![
495 Value::Scalar {
496 size_in_bits: 64,
497 kind: ScalarKind::Unsigned,
498 },
499 Value::Bool,
500 ]),
501 ]);
502 let serialized = serde_json::to_string(&value).unwrap();
503 let deserialized: Value = serde_json::from_str(&serialized).unwrap();
504 assert_eq!(value, deserialized);
505 }
506
507 #[test]
508 fn test_mscalar_deserialization() {
509 let json = r#"{"type": "mscalar", "size_in_bits": 32}"#;
510 let deserialized: Value = serde_json::from_str(json).unwrap();
511 assert_eq!(deserialized, Value::MScalar { size_in_bits: 32 });
512 }
513
514 #[test]
515 fn test_array_deserialization() {
516 let json = r#"
517 {
518 "type": "array",
519 "content": [
520 {"type": "scalar", "size_in_bits": 64},
521 {"type": "bool"}
522 ]
523 }"#;
524 let deserialized: Value = serde_json::from_str(json).unwrap();
525 assert_eq!(
526 deserialized,
527 Value::Array(vec![
528 Value::Scalar {
529 size_in_bits: 64,
530 kind: ScalarKind::Unsigned,
531 },
532 Value::Bool,
533 ])
534 );
535 }
536
537 #[test]
538 fn test_invalid_type_deserialization() {
539 let json = r#"{"type": "invalid_type"}"#;
540 let result: Result<Value, _> = serde_json::from_str(json);
541 assert!(result.is_err());
542 }
543
544 #[test]
545 fn test_missing_size_in_bits_deserialization() {
546 let json = r#"{"type": "mscalar"}"#;
547 let result: Result<Value, _> = serde_json::from_str(json);
548 assert!(result.is_err());
549 }
550
551 #[test]
552 fn test_plaintext_type_serialization() {
553 let test_cases = [
555 (
556 Value::Scalar {
557 size_in_bits: 8,
558 kind: ScalarKind::Unsigned,
559 },
560 "u8",
561 ),
562 (
563 Value::Scalar {
564 size_in_bits: 16,
565 kind: ScalarKind::Unsigned,
566 },
567 "u16",
568 ),
569 (
570 Value::Scalar {
571 size_in_bits: 32,
572 kind: ScalarKind::Unsigned,
573 },
574 "u32",
575 ),
576 (
577 Value::Scalar {
578 size_in_bits: 64,
579 kind: ScalarKind::Unsigned,
580 },
581 "u64",
582 ),
583 (
584 Value::Scalar {
585 size_in_bits: 128,
586 kind: ScalarKind::Unsigned,
587 },
588 "u128",
589 ),
590 (
592 Value::Scalar {
593 size_in_bits: 24,
594 kind: ScalarKind::Unsigned,
595 },
596 "scalar",
597 ),
598 ];
599
600 for (value, expected_type) in test_cases {
601 let serialized = serde_json::to_value(&value).unwrap();
603 let expected = match &value {
604 Value::Scalar { size_in_bits, .. } => json!({
605 "type": expected_type,
606 "size_in_bits": size_in_bits
607 }),
608 Value::Bool => json!({
609 "type": expected_type
610 }),
611 _ => unreachable!(),
612 };
613 assert_eq!(serialized, expected);
614
615 let json = serde_json::to_string(&expected).unwrap();
617 let deserialized: Value = serde_json::from_str(&json).unwrap();
618 assert_eq!(deserialized, value);
619 }
620 }
621
622 #[test]
623 fn test_signed_integer_serialization() {
624 let test_cases = [
625 (
626 Value::Scalar {
627 size_in_bits: 8,
628 kind: ScalarKind::Signed,
629 },
630 "i8",
631 ),
632 (
633 Value::Scalar {
634 size_in_bits: 16,
635 kind: ScalarKind::Signed,
636 },
637 "i16",
638 ),
639 (
640 Value::Scalar {
641 size_in_bits: 32,
642 kind: ScalarKind::Signed,
643 },
644 "i32",
645 ),
646 (
647 Value::Scalar {
648 size_in_bits: 64,
649 kind: ScalarKind::Signed,
650 },
651 "i64",
652 ),
653 (
654 Value::Scalar {
655 size_in_bits: 128,
656 kind: ScalarKind::Signed,
657 },
658 "i128",
659 ),
660 (
661 Value::Scalar {
662 size_in_bits: 24,
663 kind: ScalarKind::Signed,
664 },
665 "signed_integer",
666 ),
667 ];
668
669 for (value, expected_type) in test_cases {
670 let serialized = serde_json::to_value(&value).unwrap();
672 let expected = json!({
673 "type": expected_type,
674 "size_in_bits": match &value {
675 Value::Scalar { size_in_bits, .. } => size_in_bits,
676 _ => unreachable!(),
677 }
678 });
679 assert_eq!(serialized, expected);
680
681 let json = serde_json::to_string(&expected).unwrap();
683 let deserialized: Value = serde_json::from_str(&json).unwrap();
684 assert_eq!(deserialized, value);
685 }
686 }
687
688 #[test]
689 fn test_backward_compatibility() {
690 let old_json_cases = [
692 (r#"{"type": "u8", "size_in_bits": 8}"#, 8),
693 (r#"{"type": "u16", "size_in_bits": 16}"#, 16),
694 (r#"{"type": "u32", "size_in_bits": 32}"#, 32),
695 (r#"{"type": "u64", "size_in_bits": 64}"#, 64),
696 (r#"{"type": "u128", "size_in_bits": 128}"#, 128),
697 (r#"{"type": "scalar", "size_in_bits": 24}"#, 24),
698 ];
699
700 for (json, expected_size) in old_json_cases {
701 let deserialized: Value = serde_json::from_str(json).unwrap();
702 assert_eq!(
703 deserialized,
704 Value::Scalar {
705 size_in_bits: expected_size,
706 kind: ScalarKind::Unsigned
707 }
708 );
709 }
710 }
711
712 #[test]
713 fn test_mixed_signed_unsigned_serialization() {
714 let unsigned = Value::Scalar {
716 size_in_bits: 32,
717 kind: ScalarKind::Unsigned,
718 };
719 let signed = Value::Scalar {
720 size_in_bits: 32,
721 kind: ScalarKind::Signed,
722 };
723
724 let unsigned_json = serde_json::to_value(&unsigned).unwrap();
725 let signed_json = serde_json::to_value(&signed).unwrap();
726
727 assert_eq!(
728 unsigned_json,
729 json!({
730 "type": "u32",
731 "size_in_bits": 32
732 })
733 );
734 assert_eq!(
735 signed_json,
736 json!({
737 "type": "i32",
738 "size_in_bits": 32
739 })
740 );
741
742 assert_ne!(unsigned_json, signed_json);
744 }
745}