git-ents.gitmain
⌘K
foforge
commit f3f2418
model: distinguish unknown refs/meta/* namespaces from non-meta refs

namespace::classify returned None both for a ref outside refs/meta/* and for a meta ref in a namespace this build does not know, but the gate and receive must route the latter generically (model.extensibility: a stock server carries entity types it cannot parse). A new Namespace::Unknown variant on the #[non_exhaustive] enum keeps the two cases apart; None now means only "not forge state".

Assisted-by: Claude:claude-fable-5

Joseph D. Carpinelli · 1 month ago

Reviews

No reviews of this commit yet — record a verdict below.

Start a review

verdict

crates/ents-model/src/namespace.rs @@ -138,11 +138,22 @@ Account, /// The fixed `refs/meta/config` ref. Config, + /// Under `refs/meta/*`, but in no namespace this build of the vocabulary + /// knows. `model.extensibility` requires a stock server to carry entity + /// types it cannot parse, so the gate and `receive` must be able to + /// route an unknown meta namespace generically rather than confuse it + /// with a ref that is not forge state at all — which is why this is a + /// variant and not a `None`. + Unknown, } -/// Classify a `refs/meta/*` refname by which entity's namespace it falls in, -/// or `None` if `name` is not under `refs/meta/*` at all +/// Classify a `refs/meta/*` refname by which entity's namespace it falls in. +/// +/// Returns `None` only when `name` is not under `refs/meta/*` at all /// (`meta-ref.namespace`: "All forge state MUST live under `refs/meta/*`"). +/// A refname under `refs/meta/*` whose namespace this build does not know +/// classifies as [`Namespace::Unknown`] instead — it is still forge state +/// (`model.extensibility`), just state this vocabulary cannot interpret. /// /// # Examples /// @@ -154,8 +165,11 @@ /// /// let outside: gix::refs::FullName = "refs/heads/main".try_into().expect("valid"); /// assert_eq!(namespace::classify(outside.as_ref()), None); +/// +/// let novel: gix::refs::FullName = "refs/meta/reviews/7".try_into().expect("valid"); +/// assert_eq!(namespace::classify(novel.as_ref()), Some(Namespace::Unknown)); /// ``` -// @relation(meta-ref.namespace, meta-ref.granularity, scope=function) +// @relation(meta-ref.namespace, meta-ref.granularity, model.extensibility, scope=function) #[must_use] pub fn classify(name: &FullNameRef) -> Option<Namespace> { let path = name.as_bstr().to_string(); @@ -177,7 +191,7 @@ "toolchains" => Some(Namespace::Toolchain), "redactions" => Some(Namespace::Redaction), "inbox" => Some(Namespace::Inbox), - _ => None, + _ => Some(Namespace::Unknown), } } @@ -234,7 +248,8 @@ #[case::account("refs/meta/account", Some(Namespace::Account))] #[case::config("refs/meta/config", Some(Namespace::Config))] #[case::outside_meta("refs/heads/main", None)] - #[case::unrecognized("refs/meta/index/abc", None)] + #[case::unrecognized("refs/meta/index/abc", Some(Namespace::Unknown))] + #[case::novel_namespace("refs/meta/reviews/7", Some(Namespace::Unknown))] // @relation(meta-ref.namespace, meta-ref.granularity, scope=function, role=Verifies) fn classify_matches_the_namespace_table( #[case] refname: &str,