hugr_core/hugr/patch/simple_replace/
serial.rs

1//! Serialisation of [`SimpleReplacement`]
2
3use super::*;
4
5/// Serialized format for [`SimpleReplacement`]
6#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
7pub struct SerialSimpleReplacement<H, N> {
8    /// The subgraph to be replaced
9    pub subgraph: SiblingSubgraph<N>,
10    /// The replacement Hugr
11    pub replacement: H,
12}
13
14impl<N> SimpleReplacement<N> {
15    /// Create a new [`SimpleReplacement`] from its serialized format
16    pub fn from_serial<H: Into<Hugr>>(value: SerialSimpleReplacement<H, N>) -> Self {
17        let SerialSimpleReplacement {
18            subgraph,
19            replacement,
20        } = value;
21        SimpleReplacement {
22            subgraph,
23            replacement: replacement.into(),
24        }
25    }
26
27    /// Convert a [`SimpleReplacement`] into its serialized format
28    pub fn into_serial<H: From<Hugr>>(self) -> SerialSimpleReplacement<H, N> {
29        let SimpleReplacement {
30            subgraph,
31            replacement,
32        } = self;
33        SerialSimpleReplacement {
34            subgraph,
35            replacement: replacement.into(),
36        }
37    }
38
39    /// Create its serialized format from a reference to [`SimpleReplacement`]
40    pub fn to_serial<'a, H>(&'a self) -> SerialSimpleReplacement<H, N>
41    where
42        N: Clone,
43        H: From<&'a Hugr>,
44    {
45        let SimpleReplacement {
46            subgraph,
47            replacement,
48        } = self;
49        SerialSimpleReplacement {
50            subgraph: subgraph.clone(),
51            replacement: replacement.into(),
52        }
53    }
54}
55
56impl<N, H: From<Hugr>> From<SimpleReplacement<N>> for SerialSimpleReplacement<H, N> {
57    fn from(value: SimpleReplacement<N>) -> Self {
58        value.into_serial()
59    }
60}
61
62impl<H: Into<Hugr>, N> From<SerialSimpleReplacement<H, N>> for SimpleReplacement<N> {
63    fn from(value: SerialSimpleReplacement<H, N>) -> Self {
64        SimpleReplacement::from_serial(value)
65    }
66}
67
68#[cfg(test)]
69mod test {
70    use super::super::test::*;
71    use super::*;
72    use crate::{envelope::serde_with::AsStringEnvelope, utils::test_quantum_extension::cx_gate};
73
74    use derive_more::derive::{From, Into};
75    use rstest::rstest;
76    use serde_with::serde_as;
77
78    #[serde_as]
79    #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, From, Into)]
80    struct WrappedHugr {
81        #[serde_as(as = "AsStringEnvelope")]
82        pub hugr: Hugr,
83    }
84
85    impl<'h> From<&'h Hugr> for WrappedHugr {
86        fn from(value: &'h Hugr) -> Self {
87            WrappedHugr {
88                hugr: value.clone(),
89            }
90        }
91    }
92
93    #[rstest]
94    fn test_serial(simple_hugr: Hugr, dfg_hugr: Hugr) {
95        let h: Hugr = simple_hugr;
96        // 1. Locate the CX and its successor H's in h
97        let h_node_cx: Node = h
98            .entry_descendants()
99            .find(|node: &Node| *h.get_optype(*node) == cx_gate().into())
100            .unwrap();
101        let (h_node_h0, h_node_h1) = h.output_neighbours(h_node_cx).collect_tuple().unwrap();
102        let s: Vec<Node> = vec![h_node_cx, h_node_h0, h_node_h1].into_iter().collect();
103        // 2. Construct a new DFG-rooted hugr for the replacement
104        let replacement = dfg_hugr;
105        // 4. Define the replacement
106        let r = SimpleReplacement {
107            subgraph: SiblingSubgraph::try_from_nodes(s, &h).unwrap(),
108            replacement,
109        };
110
111        let other_repl_serial = r.to_serial::<WrappedHugr>();
112        let repl_serial = r.into_serial::<WrappedHugr>();
113
114        assert_eq!(repl_serial, other_repl_serial);
115    }
116}