Skip to main content

Facets

Struct Facets 

Source
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

Source

pub fn from_config(config: &WorkspaceConfig) -> Self

Classify against a resolved workspace config.

Source

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.

Source

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.

Source

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.

Source

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?
examples/inspect.rs (line 23)
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}
Source

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.

Source

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.

Source

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?
examples/inspect.rs (line 20)
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}
Source

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.

Trait Implementations§

Source§

impl Clone for Facets

Source§

fn clone(&self) -> Facets

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Facets

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Facets

Source§

fn default() -> Self

prov’s built-in vocabulary and nothing else — the right answer for a document read outside a workspace, which is still a prov document.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.