gatehouse_runtime_protocol/
wire.rs1use crate::{Capability, Engine, Object, Operation, Outcome, Protocol};
4use serde::de::{self, MapAccess, Visitor};
5use serde::{Deserialize, Deserializer};
6use std::fmt;
7
8#[derive(Deserialize)]
9#[serde(deny_unknown_fields)]
10struct Target {
11 object_id: String,
12}
13
14#[derive(Deserialize)]
15#[serde(deny_unknown_fields)]
16struct Present {
17 object: Object,
18}
19
20#[derive(Deserialize)]
21#[serde(deny_unknown_fields)]
22struct Capabilities {
23 supported: Vec<Capability>,
24}
25
26fn tag<'de, M: MapAccess<'de>>(map: &mut M) -> Result<String, M::Error> {
27 map.next_key()?
28 .ok_or_else(|| de::Error::custom("missing variant"))
29}
30
31fn end<'de, M: MapAccess<'de>>(map: &mut M) -> Result<(), M::Error> {
32 if map.next_key::<de::IgnoredAny>()?.is_some() {
33 return Err(de::Error::custom("multiple variant fields"));
34 }
35 Ok(())
36}
37
38struct OperationVisitor;
39impl<'de> Visitor<'de> for OperationVisitor {
40 type Value = Operation;
41
42 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
43 formatter.write_str("a string unit operation or one tagged operation object")
44 }
45
46 fn visit_str<E: de::Error>(self, value: &str) -> Result<Operation, E> {
47 match value {
48 "capabilities" => Ok(Operation::Capabilities),
49 _ => Err(E::custom("invalid string operation")),
50 }
51 }
52
53 fn visit_map<M: MapAccess<'de>>(self, mut map: M) -> Result<Operation, M::Error> {
54 let operation = match tag(&mut map)?.as_str() {
55 "inspect" => Operation::Inspect {
56 object_id: map.next_value::<Target>()?.object_id,
57 },
58 "remove" => Operation::Remove {
59 object_id: map.next_value::<Target>()?.object_id,
60 },
61 _ => return Err(de::Error::custom("invalid object operation")),
62 };
63 end(&mut map)?;
64 Ok(operation)
65 }
66}
67
68impl<'de> Deserialize<'de> for Operation {
69 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
70 deserializer.deserialize_any(OperationVisitor)
71 }
72}
73
74struct OutcomeVisitor;
75impl<'de> Visitor<'de> for OutcomeVisitor {
76 type Value = Outcome;
77
78 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
79 formatter.write_str("a string unit outcome or one tagged outcome object")
80 }
81
82 fn visit_str<E: de::Error>(self, value: &str) -> Result<Outcome, E> {
83 match value {
84 "absent" => Ok(Outcome::Absent),
85 "unavailable" => Ok(Outcome::Unavailable),
86 "completed" => Ok(Outcome::Completed),
87 "rejected-before-effect" => Ok(Outcome::RejectedBeforeEffect),
88 "unknown" => Ok(Outcome::Unknown),
89 _ => Err(E::custom("invalid string outcome")),
90 }
91 }
92
93 fn visit_map<M: MapAccess<'de>>(self, mut map: M) -> Result<Outcome, M::Error> {
94 let outcome = match tag(&mut map)?.as_str() {
95 "present" => Outcome::Present {
96 object: map.next_value::<Present>()?.object,
97 },
98 "capabilities" => Outcome::Capabilities {
99 supported: map.next_value::<Capabilities>()?.supported,
100 },
101 _ => return Err(de::Error::custom("invalid object outcome")),
102 };
103 end(&mut map)?;
104 Ok(outcome)
105 }
106}
107
108impl<'de> Deserialize<'de> for Outcome {
109 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
110 deserializer.deserialize_any(OutcomeVisitor)
111 }
112}
113
114impl TryFrom<String> for Protocol {
115 type Error = &'static str;
116 fn try_from(value: String) -> Result<Self, Self::Error> {
117 match value.as_str() {
118 "gate-runtime/v1" => Ok(Self::V1),
119 _ => Err("unsupported protocol"),
120 }
121 }
122}
123
124impl TryFrom<String> for Engine {
125 type Error = &'static str;
126 fn try_from(value: String) -> Result<Self, Self::Error> {
127 match value.as_str() {
128 "docker" => Ok(Self::Docker),
129 "podman" => Ok(Self::Podman),
130 _ => Err("unsupported engine"),
131 }
132 }
133}
134
135impl TryFrom<String> for Capability {
136 type Error = &'static str;
137 fn try_from(value: String) -> Result<Self, Self::Error> {
138 match value.as_str() {
139 "inspect" => Ok(Self::Inspect),
140 "remove" => Ok(Self::Remove),
141 _ => Err("unsupported capability"),
142 }
143 }
144}