pub struct Facets { /* private fields */ }Expand description
The classifier: one workspace’s answer to “what is this key?”.
Cheap to build and cheap to hold — it is the config’s vocabulary, resolved
once, and every lookup is a map hit. Build it from the workspace config when
there is one and take Facets::default when there is not: a lone document
opened outside any workspace is still read with prov’s built-in vocabulary,
which is what makes contents mean contents in a file nobody has
configured.
Implementations§
Source§impl Facets
impl Facets
Sourcepub fn from_config(config: &WorkspaceConfig) -> Self
pub fn from_config(config: &WorkspaceConfig) -> Self
Classify against a resolved workspace config.
Sourcepub fn relations(&self) -> &RelationSet
pub fn relations(&self) -> &RelationSet
The relation vocabulary these facets read by — what crate::links
walks, and what a frontend hands prov when it resolves a target.
Sourcepub fn of_key(&self, key: &str) -> Facet
pub fn of_key(&self, key: &str) -> Facet
Classify a top-level key.
Relations first, so a workspace that declares fields.contents — legal,
and a thing a confused config can say — still gets a link field for the
key prov will follow. The fields half only reaches keys the relation
vocabulary left alone.
Sourcepub fn of(&self, path: &[Seg]) -> Facet
pub fn of(&self, path: &[Seg]) -> Facet
Classify a metadata path.
The first segment decides, so contents[2] is the relation
contents and prov.relations.see_also.inverse is policy. That is not a
shortcut: a path’s facet is a fact about which of prov’s axes it belongs
to, and every segment below the first is a part of the same one. It also
matches how flower scopes its own managed sets, which are root keys
matched exactly — so a list built here goes into set_demoted meaning
what it meant on the way out.
An empty path — the document itself — is Facet::Carried: the document
is not one of prov’s keys.
Sourcepub fn classify(&self, meta: &Value) -> Vec<(String, Facet)>
pub fn classify(&self, meta: &Value) -> Vec<(String, Facet)>
Every top-level key of meta, in document order, with its facet.
Document order, not sorted: the order keys are written in is the document’s own and a lossless editor’s whole point. A caller that wants them grouped groups them.
Examples found in repository?
7fn main() {
8 let path = std::path::PathBuf::from(std::env::args().nth(1).expect("a document"));
9 let view = WorkspaceView::discover(&path).expect("discovery");
10 match &view {
11 Some(v) => println!("workspace: {}", v.root_dir().display()),
12 None => println!("workspace: none"),
13 }
14 let facets = view
15 .as_ref()
16 .map(|v| v.facets().clone())
17 .unwrap_or_default();
18 let schema = view.as_ref().map(|v| v.schema_for(&path));
19 let session =
20 DocumentSession::open_managed(&path, schema, facets.managed_key_names()).expect("open");
21
22 println!("\nkeys:");
23 for (key, facet) in facets.classify(session.meta()) {
24 let flags = [
25 facet.structural().then_some("structural"),
26 facet.managed().then_some("managed"),
27 ]
28 .into_iter()
29 .flatten()
30 .collect::<Vec<_>>()
31 .join(",");
32 println!(" {key:<14} {:<9} {flags}", facet.kind());
33 }
34
35 println!("\nlinks:");
36 for link in links_in(session.meta(), &facets) {
37 let landing = match &view {
38 Some(v) => v.resolve(&path, &link),
39 None => resolve_without_workspace(&path, &link),
40 };
41 let mark = if matches!(landing, Destination::Document { exists: true, .. }) {
42 "→"
43 } else {
44 "·"
45 };
46 println!(
47 " {mark} {:<10} {:<22} {}",
48 link.relation.name,
49 link.display(),
50 landing.describe()
51 );
52 }
53}Sourcepub fn structural_keys(&self, meta: &Value) -> Vec<String>
pub fn structural_keys(&self, meta: &Value) -> Vec<String>
The keys present in meta that are prov’s structure
(Facet::structural) — shaped for
Model::set_demoted.
Present in the document, not every key prov knows: demoting a key the document does not have is harmless but tells a reader nothing, and the list is short enough to be worth being exact about.
Sourcepub fn managed_keys(&self, meta: &Value) -> Vec<String>
pub fn managed_keys(&self, meta: &Value) -> Vec<String>
The keys present in meta that the workspace maintains
(Facet::managed) — shaped for the derived argument of
Model::with_managed.
Sourcepub fn managed_key_names(&self) -> Vec<String>
pub fn managed_key_names(&self) -> Vec<String>
Every key this workspace maintains, whether or not a given document
carries it — the same list as managed_keys, asked
without a document.
The form a constructor needs: flower takes its derived set before the
first row list exists, which is before there is a parsed document to ask.
Naming a key the document does not have is inert (there is no row to mark
read-only), and naming one it gains later is the point — a document that
acquires an id should not become editable in the same breath.
Examples found in repository?
7fn main() {
8 let path = std::path::PathBuf::from(std::env::args().nth(1).expect("a document"));
9 let view = WorkspaceView::discover(&path).expect("discovery");
10 match &view {
11 Some(v) => println!("workspace: {}", v.root_dir().display()),
12 None => println!("workspace: none"),
13 }
14 let facets = view
15 .as_ref()
16 .map(|v| v.facets().clone())
17 .unwrap_or_default();
18 let schema = view.as_ref().map(|v| v.schema_for(&path));
19 let session =
20 DocumentSession::open_managed(&path, schema, facets.managed_key_names()).expect("open");
21
22 println!("\nkeys:");
23 for (key, facet) in facets.classify(session.meta()) {
24 let flags = [
25 facet.structural().then_some("structural"),
26 facet.managed().then_some("managed"),
27 ]
28 .into_iter()
29 .flatten()
30 .collect::<Vec<_>>()
31 .join(",");
32 println!(" {key:<14} {:<9} {flags}", facet.kind());
33 }
34
35 println!("\nlinks:");
36 for link in links_in(session.meta(), &facets) {
37 let landing = match &view {
38 Some(v) => v.resolve(&path, &link),
39 None => resolve_without_workspace(&path, &link),
40 };
41 let mark = if matches!(landing, Destination::Document { exists: true, .. }) {
42 "→"
43 } else {
44 "·"
45 };
46 println!(
47 " {mark} {:<10} {:<22} {}",
48 link.relation.name,
49 link.display(),
50 landing.describe()
51 );
52 }
53}Sourcepub fn carried_keys(&self, meta: &Value) -> Vec<String>
pub fn carried_keys(&self, meta: &Value) -> Vec<String>
The keys present in meta that prov carries and never reads — the
complement a frontend showing “just this document’s own values” wants.