pub struct SubjectScheme { /* private fields */ }Expand description
How a subject is composed: literal segments and placeholders in braces, as
in /tenant/{tenant}/workshop/{workshop}.
A scheme works in both directions. build composes
a subject from values, and match_subject
takes one apart again, or value takes a single
value out of it, which a projection needs to recover the ID of an aggregate
that the events themselves do not carry:
use architecturekit::SubjectScheme;
let workshops = SubjectScheme::new("/tenant/{tenant}/workshop/{workshop}");
let subject = workshops.build(&["acme", "event-sourcing"]);
assert_eq!(subject.as_str(), "/tenant/acme/workshop/event-sourcing");
assert_eq!(workshops.value(&subject, "workshop"), Some("event-sourcing"));EventSourcingDB allows only ASCII letters and digits, underscores, and
hyphens in a segment of a subject (see Subject), so this is what the
literal segments of a pattern and the values of its placeholders may
contain. The names of its
placeholders follow the same rule, so that a typo, such as a brace too many,
is not taken for a name.
Implementations§
Source§impl SubjectScheme
impl SubjectScheme
Sourcepub fn new(pattern: &str) -> Self
pub fn new(pattern: &str) -> Self
Parses a pattern.
§Panics
A malformed pattern, including one with a literal segment or a placeholder name that contains a character EventSourcingDB does not allow in a subject, is a programming error, so this panics while the scheme is being built.
Sourcepub fn root(&self) -> Subject
pub fn root(&self) -> Subject
Returns the subject that every subject of the scheme lies under: the
literal segments before the first placeholder, as /tenant for
/tenant/{tenant}/workshop/{workshop}, or / if the pattern starts
with a placeholder. Reading or observing recursively from it yields the
events of all subjects the scheme describes, and possibly of others
under the same root, which match_subject
tells apart.
Sourcepub fn placeholders(&self) -> &[String]
pub fn placeholders(&self) -> &[String]
Returns the placeholder names, in the order
build expects their values.
Sourcepub fn build<V: AsRef<str>>(&self, values: &[V]) -> Subject
pub fn build<V: AsRef<str>>(&self, values: &[V]) -> Subject
Composes a subject. The values fill the placeholders in the order they appear in the pattern.
§Panics
A wrong number of values, or one that check
refuses, such as an empty one or one with a slash or a dot, is a
programming error, so this panics. Values that come from outside, such
as an ID in a request, may well be like that, so build from them with
try_build instead.
Sourcepub fn try_build<V: AsRef<str>>(
&self,
values: &[V],
) -> Result<Subject, SubjectValuesError>
pub fn try_build<V: AsRef<str>>( &self, values: &[V], ) -> Result<Subject, SubjectValuesError>
Composes a subject from values that come from outside, such as an ID in
a request, as build does, but refuses values
that check refuses, rather than panicking:
use architecturekit::SubjectScheme;
let books = SubjectScheme::new("/books/{book_id}");
assert_eq!(books.try_build(&["42"])?.as_str(), "/books/42");
assert!(books.try_build(&["a.b"]).is_err());§Errors
Fails with what check fails with.
Sourcepub fn check<V: AsRef<str>>(
&self,
values: &[V],
) -> Result<(), SubjectValuesError>
pub fn check<V: AsRef<str>>( &self, values: &[V], ) -> Result<(), SubjectValuesError>
Tells whether the values can compose a subject: one per placeholder,
none of them empty, and each made only of the characters EventSourcingDB
allows in a segment of a subject, which are A-Z, a-z, 0-9, underscores,
and hyphens. It is what build insists on, as
an error rather than a panic, for values that come from outside.
The error may reach the caller of an API, so it names the placeholder
of a value, but neither the crate nor the pattern, as in: value for
“id” must not be empty. The panic of build names both, since it is
for the developer.
§Errors
Fails if the values can not compose a subject, as described above.
Sourcepub fn match_subject<'scheme, 'subject, S>(
&'scheme self,
subject: &'subject S,
) -> Option<HashMap<&'scheme str, &'subject str>>
pub fn match_subject<'scheme, 'subject, S>( &'scheme self, subject: &'subject S, ) -> Option<HashMap<&'scheme str, &'subject str>>
Takes a subject apart, into the value of every placeholder, by its
name. It returns None if the subject does not follow the pattern,
which is an ordinary case for a projection reading recursively across
several schemes. A subject with a value that
check refuses does not follow it either, so
that this takes apart only what build
composes.
It is called match_subject rather than match, which is a keyword in
Rust. To take a single value out of a subject, use
value, which panics for a name the pattern
does not have. It takes a Subject as well as text.
Sourcepub fn value<'subject, S>(
&self,
subject: &'subject S,
placeholder: &str,
) -> Option<&'subject str>
pub fn value<'subject, S>( &self, subject: &'subject S, placeholder: &str, ) -> Option<&'subject str>
Takes the value of a single placeholder out of a subject. It returns
None if the subject does not follow the pattern, as
match_subject does. To take several
values out of the same subject, use match_subject.
§Panics
A placeholder that the pattern does not have, such as one with a typo, is a programming error, so this panics, whatever the subject is.
Trait Implementations§
Source§impl Clone for SubjectScheme
impl Clone for SubjectScheme
Source§impl Debug for SubjectScheme
impl Debug for SubjectScheme
impl Eq for SubjectScheme
Source§impl PartialEq for SubjectScheme
impl PartialEq for SubjectScheme
impl StructuralPartialEq for SubjectScheme
Auto Trait Implementations§
impl Freeze for SubjectScheme
impl RefUnwindSafe for SubjectScheme
impl Send for SubjectScheme
impl Sync for SubjectScheme
impl Unpin for SubjectScheme
impl UnsafeUnpin for SubjectScheme
impl UnwindSafe for SubjectScheme
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request