feat(interface-types) Make unwraps safe by introducing more errors.

This commit is contained in:
Ivan Enderlin
2020-04-02 16:38:40 +02:00
parent b0af014339
commit e385bf66c7

View File

@ -114,9 +114,19 @@ where
let mut serializer = Serializer::new(); let mut serializer = Serializer::new();
value.serialize(&mut serializer)?; value.serialize(&mut serializer)?;
assert_eq!(serializer.values.len(), 1); if serializer.values.len() != 1 {
Err(SerializeError::TransformationNotFinished)
} else {
let mut first_values = serializer.values.pop().unwrap(); // this `unwrap` is safe because we are sure the length is 1.
Ok(serializer.values.pop().unwrap().pop().unwrap()) if first_values.len() != 1 {
Err(SerializeError::TransformationNotFinished)
} else {
let first_value = first_values.pop().unwrap(); // this `unwrap` is safe because we are sure the length is 1.
Ok(first_value)
}
}
} }
/// The deserializer. The iterator iterates over `InterfaceValue`s, /// The deserializer. The iterator iterates over `InterfaceValue`s,
@ -535,16 +545,25 @@ impl Serializer {
self.values.push(Vec::with_capacity(capacity)); self.values.push(Vec::with_capacity(capacity));
} }
fn pop(&mut self) -> Vec<InterfaceValue> { fn pop(&mut self) -> Result<Vec<InterfaceValue>, SerializeError> {
assert!(self.values.len() >= 2); if self.values.len() < 2 {
Err(SerializeError::InternalValuesCorrupted)
self.values.pop().unwrap() } else {
Ok(self.values.pop().unwrap()) // this `unwrap` is safe before `self.values` contains at least 2 items
}
} }
} }
/// Represents an error while serializing. /// Represents an error while serializing.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum SerializeError { pub enum SerializeError {
/// The serialization still has pending values internally.
TransformationNotFinished,
/// The internal values have been corrupted during the
/// serialization.
InternalValuesCorrupted,
/// Arbitrary message. /// Arbitrary message.
Message(String), Message(String),
} }
@ -558,6 +577,14 @@ impl ser::Error for SerializeError {
impl Display for SerializeError { impl Display for SerializeError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
Self::TransformationNotFinished => write!(
formatter,
"serialization still has pending values internally, something incorrect happened"
),
Self::InternalValuesCorrupted => write!(
formatter,
"the internal values have been corrutped during the serialization"
),
Self::Message(ref msg) => write!(formatter, "{}", msg), Self::Message(ref msg) => write!(formatter, "{}", msg),
} }
} }
@ -804,7 +831,7 @@ impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
} }
fn end(self) -> Result<Self::Ok, Self::Error> { fn end(self) -> Result<Self::Ok, Self::Error> {
let record = InterfaceValue::Record(self.pop()); let record = InterfaceValue::Record(self.pop()?);
self.last().push(record); self.last().push(record);
Ok(()) Ok(())
@ -862,7 +889,7 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer {
} }
fn end(self) -> Result<Self::Ok, Self::Error> { fn end(self) -> Result<Self::Ok, Self::Error> {
let record = InterfaceValue::Record(self.pop()); let record = InterfaceValue::Record(self.pop()?);
self.last().push(record); self.last().push(record);
Ok(()) Ok(())