in akd_mysql/src/mysql_storables.rs [453:572]
fn from_row<St: Storable>(row: &mut mysql_async::Row) -> core::result::Result<Self, MySqlError>
where
Self: std::marker::Sized,
{
fn cast_err() -> MySqlError {
MySqlError::from("Failed to cast label:val into [u8; 32]".to_string())
}
match St::data_type() {
StorageType::Azks => {
// epoch, num_nodes
if let (Some(Ok(epoch)), Some(Ok(num_nodes))) = (row.take_opt(0), row.take_opt(1)) {
let azks = DbRecord::build_azks(epoch, num_nodes);
return Ok(DbRecord::Azks(azks));
}
}
StorageType::HistoryNodeState => {
// label_len, label_val, epoch, value, child_states
if let (
Some(Ok(label_len)),
Some(Ok(label_val)),
Some(Ok(epoch)),
Some(Ok(value)),
Some(Ok(child_states)),
) = (
row.take_opt(0),
row.take_opt(1),
row.take_opt(2),
row.take_opt(3),
row.take_opt(4),
) {
let value_vec: Vec<u8> = value;
let label_val_vec: Vec<u8> = label_val;
let child_states_bin_vec: Vec<u8> = child_states;
let child_states_decoded: [Option<HistoryChildState>; ARITY] =
bincode::deserialize(&child_states_bin_vec).map_err(
|serialization_err| {
MySqlError::Other(
format!("Serialization error {}", serialization_err).into(),
)
},
)?;
let node_state = DbRecord::build_history_node_state(
value_vec.try_into().map_err(|_| cast_err())?,
child_states_decoded,
label_len,
label_val_vec.try_into().map_err(|_| cast_err())?,
epoch,
);
return Ok(DbRecord::HistoryNodeState(node_state));
}
}
StorageType::HistoryTreeNode => {
// `label_len`, `label_val`, `birth_epoch`, `last_epoch`, `parent_label_len`, `parent_label_val`, `node_type`
if let (
Some(Ok(label_len)),
Some(Ok(label_val)),
Some(Ok(birth_epoch)),
Some(Ok(last_epoch)),
Some(Ok(parent_label_len)),
Some(Ok(parent_label_val)),
Some(Ok(node_type)),
) = (
row.take_opt(0),
row.take_opt(1),
row.take_opt(2),
row.take_opt(3),
row.take_opt(4),
row.take_opt(5),
row.take_opt(6),
) {
let label_val_vec: Vec<u8> = label_val;
let parent_label_val_vec: Vec<u8> = parent_label_val;
let node = DbRecord::build_history_tree_node(
label_val_vec.try_into().map_err(|_| cast_err())?,
label_len,
birth_epoch,
last_epoch,
parent_label_val_vec.try_into().map_err(|_| cast_err())?,
parent_label_len,
node_type,
);
return Ok(DbRecord::HistoryTreeNode(node));
}
}
StorageType::ValueState => {
// `username`, `epoch`, `version`, `node_label_val`, `node_label_len`, `data`
if let (
Some(Ok(username)),
Some(Ok(epoch)),
Some(Ok(version)),
Some(Ok(node_label_val)),
Some(Ok(node_label_len)),
Some(Ok(data)),
) = (
row.take_opt(0),
row.take_opt(1),
row.take_opt(2),
row.take_opt(3),
row.take_opt(4),
row.take_opt(5),
) {
let node_label_val_vec: Vec<u8> = node_label_val;
let state = DbRecord::build_user_state(
username,
data,
version,
node_label_len,
node_label_val_vec.try_into().map_err(|_| cast_err())?,
epoch,
);
return Ok(DbRecord::ValueState(state));
}
}
}
// fallback
let err = MySqlError::Driver(mysql_async::DriverError::FromRow { row: row.clone() });
Err(err)
}