Skip to main content

StorePath

Struct StorePath 

Source
pub struct StorePath { /* private fields */ }
Expand description

Where a value lives in the store, as the levels it is under.

A path is built from segments and only from segments, so a name is a name: putting "dark.mode" in one addresses a single value with a dot in it, not two levels.

Two forms answer the two kinds of engine, and a path holds whichever one it arrived in. A flat engine keeps a key whole and addresses it by the joined spelling; a document engine keeps a level at a time and addresses it by the levels. The other form is built on the first reader that wants it and kept, so a path costs one of the two, and a scan that never asks for the other never pays for it.

Which is not a detail: both directions are taken per key of every scan. Splitting a key allocates for the list of levels; spelling levels out walks them for a separator and an escape and builds a string. Whichever a caller does not read is the whole of that cost.

Implementations§

Source§

impl StorePath

Source

pub const fn root() -> Self

The path that is under nothing.

Source

pub const fn from_static( segments: &'static [&'static str], joined: &'static str, ) -> Self

A path whose levels are known when the code is compiled.

Both forms are handed over ready, so this allocates nothing: no level may be empty, and joined must be exactly the joined spelling a path keeps for segments, escapes and all.

Both are checked here rather than trusted. The check is a const fn, so a path written into a const - StateScope::PATH, which is where these come from - fails to compile when the halves disagree, whether a macro or a hand-written impl wrote them. A const panic carries no formatting, so it names the invariant and not the level; the #[amethystate(prefix = ...)] macro checks the same two things first and points at the attribute.

§Panics

If any level is empty, or if joined is not the joined form of segments. At compile time when the call is in a const context, which is the only place it is meant to be.

Source

pub fn segment(name: impl AsRef<str>) -> Self

One level named name, whatever name contains - the empty name included.

A level’s name is the caller’s to choose and every document format this library writes lets a member be named with nothing, so a name that is empty is a name. It is the joined spelling that cannot carry one alone: "" reads back as the root, so the one-level path [""] has no spelling of its own and a flat text document cannot hold it.

Source

pub fn as_one_level(&self) -> Self

The whole of this path as one level, its spelling being the name.

What a store with no levels is addressed by: ui.theme becomes one level called ui.theme, and a level of the original holding a . keeps the escape that tells it from a separator, so the two spell differently here as well.

§Panics

If this is the root, which spells nothing and so names no level.

Source

pub fn from_segments<I, S>(segments: I) -> Self
where I: IntoIterator<Item = S>, S: AsRef<str>,

A path out of the levels it is under, outermost first.

No levels at all is the root, and here that is a statement rather than an accident: an as_root struct’s path is written out as no levels. A list that came from data and turned out empty is somebody’s filter rather than somebody’s decision, and goes through StorePath::try_from_segments, which refuses it. StorePath::try_from_segments refuses it, because a list that came from data and turned out empty is not something anyone said.

Source

pub fn try_from_segments<I, S>(segments: I) -> Result<Self, StorePathError>
where I: IntoIterator<Item = S>, S: AsRef<str>,

StorePath::from_segments for levels that can turn out to be empty.

Which is where the two differ: a written-out empty list means the root, and a computed one that filtered down to nothing means nobody decided. The second is refused with StorePathError::EmptyPath, because it would name the whole store, and a write through it would replace everything.

Source

pub fn push(&self, name: impl AsRef<str>) -> Self

This path with one more level under it, whatever name contains.

Source

pub fn push_shared(&self, name: SmolStr) -> Self

StorePath::push taking a name the caller already holds shared.

What a document engine has: a level’s name is stored as one of these, and a scan puts a path together out of names it is holding anyway. The other form copies the name into a fresh one per key.

Source

pub fn join(&self, other: &StorePath) -> Self

This path with other’s levels under it.

Source

pub fn segments(&self) -> impl ExactSizeIterator<Item = Level<'_>> + '_

The levels, outermost first.

Borrowed where the level is a run of the joined form, which is every level whose name carries no separator to escape.

Source

pub fn segment_at(&self, index: usize) -> Option<Level<'_>>

One level, or None past the end.

Source

pub fn is_root(&self) -> bool

Whether this path names the whole store rather than anything in it.

Answered per state rather than through len, because counting the levels of a joined key walks the whole of it - and that is the state a flat engine’s keys arrive in, asked once per key of every scan through level_under.

Source

pub fn len(&self) -> usize

How many levels the path has.

There is deliberately no is_empty beside it. A path of no levels is the root - the one that names the whole store - and that is a thing rather than the absence of one, so is_root is what asks. is_empty would be a second name for the same question, and the worse of the two.

Source

pub fn starts_with(&self, prefix: &StorePath) -> bool

Whether every level of prefix starts this path.

Compared level by level, so ui does not start uix.width - which comparing the joined strings would say it does.

Source

pub fn strip_prefix(&self, prefix: &StorePath) -> Option<StorePath>

The levels below prefix, or None when prefix does not start this path.

Source

pub fn overlaps(&self, other: &StorePath) -> bool

Whether this subtree and other’s hold any key in common.

Two subtrees are nested or apart and never half over each other, so this is two containment tests and equality needs no arm of its own: starts_with admits the prefix itself.

Source

pub fn parent(&self) -> Option<StorePath>

The path one level up, or None at the root.

Shares the level list rather than copying it short: walking up is asked for one ancestor after another, and each answer used to be the whole list copied to drop the end of it.

Source

pub fn upwards(&self) -> impl Iterator<Item = StorePath> + '_

This path and every path it sits under, nearest first, the root last.

The set a place that holds this one can be at: a path is held at itself or at one of its ancestors, and nowhere else. Walking it costs one level list, made once and shared by every step - where asking for a parent and then its parent used to copy the list per step, and throw each copy away after a comparison.

Source

pub fn name(&self) -> Option<Level<'_>>

The last level, or None at the root.

Source

pub fn level_under(&self, prefix: &StorePath) -> Under<'_>

Where this path sits under prefix, and the level it sits at.

The method level_under would be if it had nothing to check. That one takes a key an engine read off a disk and can refuse it; a path has already been through that, so this only reads.

Which is what lets the rest of the library ask the question without holding a key: an entry one level down and one two levels down are different answers, and telling them apart is a map’s whole business.

Source

pub fn name_under(&self, prefix: &StorePath) -> Option<Level<'_>>

The level that follows prefix, read straight off the joined form.

The same answer as starts_with(prefix) followed by segment_at(prefix.len()), reached without splitting either path into levels. That matters where it is used: a scan hands back a path per stored key, and the caller wants one name from each, so splitting every key into a level per allocation is work thrown away as soon as it is done.

Borrowed unless the name carries an escaped separator, which is the only case where the level is not a run of the joined string.

Source

pub fn entry_name<'k>(&self, key: &'k StorePath) -> Option<Level<'k>>

The name key is stored under, below this path: the last level of what remains, where StorePath::name_under is the first.

Taking a prefix off does not touch the end, so the last level of what remains is the last level of key - there is no remainder to build, and the name is borrowed out of key rather than copied out of it.

Source

pub fn parse_joined(joined: &str) -> Result<Self, StorePathError>

Reads a joined spelling back into the path it spells.

Only for data already on disk: a path in code is built from its segments, so nothing else needs to parse one. Fallible because a key this library did not write can hold a level with no name, and such a path is not one.

Source§

impl StorePath

Source

pub fn key(&self) -> Key

This path as a key.

Source

pub fn write_key(&self, out: &mut KeyBytes)

The same, into a buffer the caller keeps between keys.

Trait Implementations§

Source§

impl Clone for StorePath

Source§

fn clone(&self) -> Self

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 StorePath

Source§

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

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

impl<'de> Deserialize<'de> for StorePath

Read back through StorePath::parse_joined, so the invariants are checked where the document is read rather than wherever somebody first asks for a level: a key with a nameless level or a dangling escape is refused here and cannot reach anything that would have to answer for it later.

Source§

fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for StorePath

The joined spelling, written a level at a time rather than built and then written: printing a path is not a reason to make one hold a second form of itself.

Source§

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

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

impl Eq for StorePath

Source§

impl<'a> From<&'a StorePath> for PathRef<'a>

Borrowing a path costs nothing and checks nothing: it has been through the check already.

Source§

fn from(path: &'a StorePath) -> Self

Converts to this type from the input type.
Source§

impl From<&StorePath> for Key

Source§

fn from(path: &StorePath) -> Self

Converts to this type from the input type.
Source§

impl From<StaticPath> for StorePath

Source§

fn from(at: StaticPath) -> Self

Converts to this type from the input type.
Source§

impl Hash for StorePath

By the levels, so it agrees with Eq however the path arrived.

str’s own Hash ends what it writes, so two levels cannot run together into the hash of one - ["a", "b"] and ["ab"] are different paths and hash differently.

Source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl IntoStorePath for StorePath

Source§

impl IntoStorePath for &StorePath

Source§

impl MapEntryPath for StorePath

Source§

fn entry(&self, name: &str) -> StorePath

The path of the entry name sits at.
Source§

impl Ord for StorePath

The order a store lists in: by the levels, outermost first.

The flat engines range over Key, whose byte order is this order, so anything sorting paths for itself agrees with them by construction.

Not by the joined spelling. Joining puts a separator between levels and escapes it inside them, and a name holding a byte below that separator then sorts on the wrong side of a boundary: ["a!"] comes after ["a", "b"] by levels and before it by spelling. The levels are what a path is, and Key encodes them so that a flat engine’s byte order says the same thing.

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for StorePath

Equal paths are the ones that address the same place, which is the ones holding the same levels - the same question Ord answers, asked of the same form, so the two cannot drift apart.

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialEq<StorePath> for PathRef<'_>

Source§

fn eq(&self, other: &StorePath) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for StorePath

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Serialize for StorePath

Written as the joined form, which is the only form a document holds.

Source§

fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>

Serialize this value into the given Serde serializer. Read more

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> Attachment for T

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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> FieldValue for T
where T: DeserializeOwned + Serialize + Clone + Send + Sync + 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> OpaqueAttachment for T
where T: Send + Sync + 'static,

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> ToSmolStr for T
where T: Display + ?Sized,

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. 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.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more