use crate::adt::FieldPosition;
use crate::deserializer::DeserializationContext;
use crate::serializer::SerializationContext;
use crate::{BinaryDeserializer, BinaryInput, BinaryOutput, BinarySerializer, DeduplicatedString};
#[derive(Debug)]
pub enum Evolution {
InitialVersion,
FieldAdded {
name: String,
},
FieldMadeOptional {
name: String,
},
FieldRemoved {
name: String,
},
FieldMadeTransient {
name: String,
},
}
#[derive(Debug)]
pub(crate) enum SerializedEvolutionStep {
FieldAddedToNewChunk { size: i32 },
FieldMadeOptional { position: FieldPosition },
FieldRemoved { field_name: String },
Unknown,
}
const UNKNOWN: i32 = 0;
const FIELD_MADE_OPTIONAL: i32 = -1;
const FIELD_REMOVED: i32 = -2;
impl BinarySerializer for SerializedEvolutionStep {
fn serialize<Output: BinaryOutput>(
&self,
context: &mut SerializationContext<Output>,
) -> crate::Result<()> {
match self {
SerializedEvolutionStep::FieldAddedToNewChunk { size } => {
context.write_var_i32(*size);
Ok(())
}
SerializedEvolutionStep::FieldMadeOptional { position } => {
context.write_var_i32(FIELD_MADE_OPTIONAL);
position.serialize(context)
}
SerializedEvolutionStep::FieldRemoved { field_name } => {
context.write_var_i32(FIELD_REMOVED);
DeduplicatedString(field_name.clone()).serialize(context)
}
SerializedEvolutionStep::Unknown => {
context.write_var_i32(UNKNOWN);
Ok(())
}
}
}
}
impl BinaryDeserializer for SerializedEvolutionStep {
fn deserialize(context: &mut DeserializationContext<'_>) -> crate::Result<Self> {
let code_or_size = context.read_var_i32()?;
if code_or_size == UNKNOWN {
return Ok(SerializedEvolutionStep::Unknown);
}
if code_or_size == FIELD_MADE_OPTIONAL {
let position = FieldPosition::deserialize(context)?;
return Ok(SerializedEvolutionStep::FieldMadeOptional { position });
}
if code_or_size == FIELD_REMOVED {
let field_name = DeduplicatedString::deserialize(context)?.0;
return Ok(SerializedEvolutionStep::FieldRemoved { field_name });
}
Ok(SerializedEvolutionStep::FieldAddedToNewChunk { size: code_or_size })
}
}