in router/src/http/types.rs [41:137]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Internal {
Single(String),
Multiple(Vec<String>),
}
struct PredictInputVisitor;
impl<'de> Visitor<'de> for PredictInputVisitor {
type Value = PredictInput;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str(
"a string, \
a pair of strings [string, string] \
or a batch of mixed strings and pairs [[string], [string, string], ...]",
)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(PredictInput::Single(Sequence::Single(v.to_string())))
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let sequence_from_vec = |mut value: Vec<String>| {
// Validate that value is correct
match value.len() {
1 => Ok(Sequence::Single(value.pop().unwrap())),
2 => {
// Second element is last
let second = value.pop().unwrap();
let first = value.pop().unwrap();
Ok(Sequence::Pair(first, second))
}
// Sequence can only be a single string or a pair of strings
_ => Err(de::Error::invalid_length(value.len(), &self)),
}
};
// Get first element
// This will determine if input is a batch or not
let s = match seq
.next_element::<Internal>()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?
{
// Input is not a batch
// Return early
Internal::Single(value) => {
// Option get second element
let second = seq.next_element()?;
if seq.next_element::<String>()?.is_some() {
// Error as we do not accept > 2 elements
return Err(de::Error::invalid_length(3, &self));
}
if let Some(second) = second {
// Second element exists
// This is a pair
return Ok(PredictInput::Single(Sequence::Pair(value, second)));
} else {
// Second element does not exist
return Ok(PredictInput::Single(Sequence::Single(value)));
}
}
// Input is a batch
Internal::Multiple(value) => sequence_from_vec(value),
}?;
let mut batch = Vec::with_capacity(32);
// Push first sequence
batch.push(s);
// Iterate on all sequences
while let Some(value) = seq.next_element::<Vec<String>>()? {
// Validate sequence
let s = sequence_from_vec(value)?;
// Push to batch
batch.push(s);
}
Ok(PredictInput::Batch(batch))
}
}
deserializer.deserialize_any(PredictInputVisitor)
}