pub struct RoutingModifiers<'a> { /* private fields */ }Expand description
The type returned by Blueprint::prefix and Blueprint::domain.
Customize routing behaviour for a subset of routes.
Implementations§
Source§impl<'a> RoutingModifiers<'a>
impl<'a> RoutingModifiers<'a>
Sourcepub fn domain(self, domain: &str) -> Self
pub fn domain(self, domain: &str) -> Self
Only requests to the specified domain will be forwarded to routes nested under this condition.
Check out Blueprint::domain for more details.
Sourcepub fn prefix(self, prefix: &str) -> Self
pub fn prefix(self, prefix: &str) -> Self
Prepends a common prefix to all routes nested under this condition.
If a prefix has already been set, it will be overridden.
Check out Blueprint::prefix for more details.
Sourcepub fn nest(self, bp: Blueprint)
pub fn nest(self, bp: Blueprint)
Nest a Blueprint, optionally applying a common prefix and a domain restriction to all its routes.
Nesting also has consequences when it comes to constructors’ visibility.
§Constructors
Constructors registered against the parent blueprint will be available to the nested blueprint—they are inherited. Constructors registered against the nested blueprint will not be available to other sibling blueprints that are nested under the same parent—they are private.
Check out the example below to better understand the implications of nesting blueprints.
§Visibility
use pavex::{blueprint::from, Blueprint};
fn app() -> Blueprint {
let mut bp = Blueprint::new();
bp.constructor(DB_CONNECTION_POOL);
bp.nest(home_bp());
bp.nest(user_bp());
bp
}
/// All property-related routes and constructors.
fn home_bp() -> Blueprint {
let mut bp = Blueprint::new();
bp.import(from![crate::home]);
bp.routes(from![crate::home]);
bp
}
/// All user-related routes and constructors.
fn user_bp() -> Blueprint {
let mut bp = Blueprint::new();
bp.import(from![crate::user]);
bp.routes(from![crate::user]);
bp
}
#[pavex::singleton]
pub fn db_connection_pool() -> ConnectionPool {
// [...]
}
pub mod home {
// [...]
}
pub mod user {
pub fn get_session() -> Session {
// [...]
}
// [...]
}In this example, we import two constructors:
crate::user::get_session, forSession;crate::db_connection_pool, forConnectionPool.
The constructors defined in the crate::user module are only imported by the user_bp blueprint.
Since we are nesting the user_bp blueprint, those constructors will only be available
to the routes declared in the user_bp blueprint.
If a route declared in home_bp tries to inject a Session, Pavex will report an error
at compile-time, complaining that there is no registered constructor for Session.
In other words, all constructors imported in the user_bp blueprint are private
and isolated from the rest of the application.
The db_connection_pool constructor, instead, is declared against the parent blueprint
and will therefore be available to all routes declared in home_bp and user_bp—i.e.
nested blueprints inherit all the constructors declared against their parent(s).
§Precedence
If a constructor is declared against both the parent and one of its nested blueprints, the one declared against the nested blueprint takes precedence.
use pavex::{blueprint::from, Blueprint};
fn app() -> Blueprint {
let mut bp = Blueprint::new();
// These constructors are registered against the root blueprint and they're visible
// to all nested blueprints.
bp.import(from![crate::global]);
bp.nest(user_bp());
// [..]
bp
}
fn user_bp() -> Blueprint {
let mut bp = Blueprint::new();
// They can be overridden by a constructor for the same type registered
// against a nested blueprint.
// All routes in `user_bp` will use `user::get_session` instead of `global::get_session`.
bp.import(from![crate::user]);
// [...]
bp
}
pub mod global {
pub fn get_session() -> Session {
// [...]
}
}
pub mod user {
pub fn get_session() -> Session {
// [...]
}
}§Singletons
There is one exception to the precedence rule: singletons.
Pavex guarantees that there will be only one instance of a singleton type for the entire
lifecycle of the application. What should happen if two different constructors are registered for
the same Singleton type by two nested blueprints that share the same parent?
We can’t honor both constructors without ending up with two different instances of the same
type, which would violate the singleton contract.
It goes one step further! Even if those two constructors are identical, what is the expected behaviour? Does the user expect the same singleton instance to be injected in both blueprints? Or does the user expect two different singleton instances to be injected in each nested blueprint?
To avoid this ambiguity, Pavex takes a conservative approach: a singleton constructor must be registered exactly once for each type. If multiple nested blueprints need access to the singleton, the constructor must be registered against a common parent blueprint—the root blueprint, if necessary.
Sourcepub fn routes(self, import: Import)
pub fn routes(self, import: Import)
Register a group of routes.
Their path will be prepended with a common prefix if one was provided via .prefix().
They will be restricted to a specific domain if one was specified via .domain().
§Example
use pavex::{Blueprint, blueprint::from};
let mut bp = Blueprint::new();
bp.prefix("/api").routes(from![crate::api]);Auto Trait Implementations§
impl<'a> Freeze for RoutingModifiers<'a>
impl<'a> RefUnwindSafe for RoutingModifiers<'a>
impl<'a> Send for RoutingModifiers<'a>
impl<'a> Sync for RoutingModifiers<'a>
impl<'a> Unpin for RoutingModifiers<'a>
impl<'a> !UnwindSafe for RoutingModifiers<'a>
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<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling [Attribute] value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi [Quirk] value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the [Condition] value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);