feat: add `Row` and `load_rows`/`store_rows` to git-store
commit
0cb2b7dfeat: add `Row` and `load_rows`/`store_rows` to git-store
A two-field string row — the shape Signer, Check, and RunOutcome
share — wraps and unwraps to its on-disk (key, value) pair in one place
rather than by hand at every load and store.
feat: add git_store::Row bridging a named struct to a stored pair
feat: add Store::load_rows/store_rows over a MapDoc
Assisted-by: Claude:claude-opus-4-8
Reviews
No reviews of this commit yet — record a verdict below.
Start a review
crates/git-store/src/lib.rs
@@ -66,6 +66,18 @@
fn into_entries(self) -> BTreeMap<String, String>;
}
+/// One `(key, value)` entry of a [`MapDoc`] presented as a named type. The set
+/// documents expose legible structs (`Signer`, `Check`, `RunOutcome`) rather
+/// than bare pairs; this trait is the single bridge between such a struct and
+/// the `(key, value)` shape stored on disk, so the wrap/unwrap is written once
+/// here instead of at every load and store.
+pub trait Row {
+ /// Build a row from its stored `key` and `value`.
+ fn from_pair(key: String, value: String) -> Self;
+ /// The row's `(key, value)`, consuming it.
+ fn into_pair(self) -> (String, String);
+}
+
/// A repository's typed `refs/meta/*` store.
///
/// Refs are read and updated through the high-level [`gix`] API, while all
@@ -148,6 +160,30 @@
self.store(refname, &T::from_entries(entries), message)
}
+ /// Load the [`MapDoc`] `D` on `refname` as its [`Row`] values `R`, or an
+ /// empty vec when the ref is absent.
+ pub fn load_rows<D: MapDoc, R: Row>(&self, refname: &str) -> Result<Vec<R>, Error> {
+ Ok(self
+ .load_entries::<D>(refname)?
+ .into_iter()
+ .map(|(key, value)| R::from_pair(key, value))
+ .collect())
+ }
+
+ /// Store `rows` as the [`MapDoc`] `D` on `refname` as a new commit.
+ pub fn store_rows<D: MapDoc, R: Row>(
+ &self,
+ refname: &str,
+ rows: impl IntoIterator<Item = R>,
+ message: &str,
+ ) -> Result<(), Error> {
+ self.store_entries::<D>(
+ refname,
+ rows.into_iter().map(Row::into_pair).collect(),
+ message,
+ )
+ }
+
/// The documents on `refname`'s commit chain as `(committer date, value)`
/// pairs, newest first — one entry per commit, following first parents.
pub fn history<T: for<'a> Facet<'a>>(&self, refname: &str) -> Result<Vec<(u64, T)>, Error> {