use haematite::branch::ForkWrite;
use serde::{Deserialize, Serialize};
use super::{Captured, Failure, Storage, identifier, reads};
use crate::serve::protocol::Version;
const PROVENANCE_KEY: &[u8] = b"b\0fork";
#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ForkProvenance {
pub branch: String,
pub version: Version,
}
pub(super) fn provenance_write(
writer: &haematite::db::branches::BranchDatabase,
branch: &str,
at: Version,
) -> Result<ForkWrite, Failure> {
Ok(ForkWrite {
shard_id: writer.shard_for(PROVENANCE_KEY),
key: PROVENANCE_KEY.to_vec(),
value: Some(
serde_json::to_vec(&ForkProvenance {
branch: branch.to_owned(),
version: at,
})
.map_err(Failure::storage)?,
),
})
}
pub(super) fn read_provenance(
reader: &haematite::db::ReadOnlyDatabase,
at: &Captured,
) -> Result<ForkProvenance, Failure> {
provenance(reader, at)?.ok_or_else(|| {
Failure::new(
"fork_provenance_missing",
"branch has no recorded fork origin",
)
})
}
pub(super) fn provenance(
reader: &haematite::db::ReadOnlyDatabase,
at: &Captured,
) -> Result<Option<ForkProvenance>, Failure> {
let Some(bytes) = reads::get_bytes(reader, at, PROVENANCE_KEY)? else {
return Ok(None);
};
let provenance: ForkProvenance = serde_json::from_slice(&bytes).map_err(Failure::storage)?;
identifier(&provenance.branch)?;
Ok(Some(provenance))
}
impl Storage {
pub fn fork_provenance(&self, at: &Captured) -> Result<ForkProvenance, Failure> {
read_provenance(&self.reader, at)
}
}