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::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 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 (
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 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 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 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 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 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 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 assert_ne!(unsigned_json, signed_json);
705 }
706}