diff --git a/.lock b/.lock new file mode 100755 index 00000000..e69de29b diff --git a/composable/all.html b/composable/all.html new file mode 100644 index 00000000..46716bde --- /dev/null +++ b/composable/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Derive Macros

Functions

Type Aliases

Constants

\ No newline at end of file diff --git a/composable/dependencies/fn.with_dependencies.html b/composable/dependencies/fn.with_dependencies.html new file mode 100644 index 00000000..4b69f140 --- /dev/null +++ b/composable/dependencies/fn.with_dependencies.html @@ -0,0 +1,3 @@ +with_dependencies in composable::dependencies - Rust

Function composable::dependencies::with_dependencies

source ·
pub fn with_dependencies<T: Tuple, F: FnOnce() -> R, R>(with: T, f: F) -> R
Expand description

Supply a tuple of dependencies for the supplied closure

+

For a single value with_dependency may be used instead.

+
\ No newline at end of file diff --git a/composable/dependencies/fn.with_dependency.html b/composable/dependencies/fn.with_dependency.html new file mode 100644 index 00000000..547cd1e1 --- /dev/null +++ b/composable/dependencies/fn.with_dependency.html @@ -0,0 +1,3 @@ +with_dependency in composable::dependencies - Rust

Function composable::dependencies::with_dependency

source ·
pub fn with_dependency<T: 'static, F: FnOnce() -> R, R>(with: T, f: F) -> R
Expand description

Supply a single dependency for the supplied closure.

+

A convenience function that just forwards to with_dependencies.

+
\ No newline at end of file diff --git a/composable/dependencies/index.html b/composable/dependencies/index.html new file mode 100644 index 00000000..963fd416 --- /dev/null +++ b/composable/dependencies/index.html @@ -0,0 +1,30 @@ +composable::dependencies - Rust

Module composable::dependencies

source ·
Expand description

Ergonomic dependency handling.

+

Dependencies are the functions that represent resources and effects needed by the application that are outside if its the control: from network requests and file system access all the way down to random number generators and the measurement of time.

+

Dependency Injection, Dependency Mocking, and other patterns and frameworks are all designed to avoid the problems that application dependencies cause for testing: reliability and performance both suffer.

+

This crate attempts make dependency handling easy; encouraging it use.

+ +

Structs§

  • A wrapper type for accessing dependencies

Traits§

Functions§

\ No newline at end of file diff --git a/composable/dependencies/sidebar-items.js b/composable/dependencies/sidebar-items.js new file mode 100644 index 00000000..936b560c --- /dev/null +++ b/composable/dependencies/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["with_dependencies","with_dependency"],"struct":["Dependency"],"trait":["DependencyDefault"]}; \ No newline at end of file diff --git a/composable/dependencies/struct.Dependency.html b/composable/dependencies/struct.Dependency.html new file mode 100644 index 00000000..5790766b --- /dev/null +++ b/composable/dependencies/struct.Dependency.html @@ -0,0 +1,82 @@ +Dependency in composable::dependencies - Rust

Struct composable::dependencies::Dependency

source ·
pub struct Dependency<T: 'static> { /* private fields */ }
Expand description

A wrapper type for accessing dependencies

+

Implementations§

source§

impl<T> Dependency<T>

    +
  • The methods of Dependency are very similar to those of std::option::Option, as +dependencies are optionally present.
  • +
  • However, a Dependency on a type with a DependencyDefault also implements the +AsRef, Deref and Borrow traits. Event if a value has not been explicitly +registered for it, the Dependency will still be able to as_ref, deref and +borrow this default value.
  • +
+
source

pub fn new() -> Self

Creates a optional reference to the dependency of type T.

+
source

pub fn is_some(&self) -> bool

Returns true if the dependency is a Some value.

+
source

pub fn is_some_and(&self, f: impl FnOnce(&T) -> bool) -> bool

Returns true if the dependency is a Some and the value inside of it matches a predicate.

+
source

pub fn is_none(&self) -> bool

Returns true if the dependency is a None value.

+
source

pub fn as_slice(&self) -> &[T]

Returns a slice of the dependency value, if any. If this is None, an empty slice is returned.

+
source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the dependency value, if any.

+
source

pub fn expect(&self, msg: &str) -> &T

Returns the dependency Some value.

+
§Panics
+

Panics if the dependency is a None with a custom panic message provided by msg.

+
source

pub fn unwrap(&self) -> &T

Returns the contained Some value.

+
§Panics
+

Panics if the dependency value equals None.

+
source

pub fn unwrap_or(&self, default: T) -> Ref<'_, T>

Returns the dependency Some value or a provided default.

+
source

pub fn unwrap_or_else<F>(&self, f: F) -> Ref<'_, T>
where + F: FnOnce() -> T,

Returns the dependency Some value or computes it from a closure.

+
source

pub fn unwrap_or_default(&self) -> Ref<'_, T>
where + T: Default,

Returns the dependency Some value or a default.

+
source

pub fn map<U, F>(&self, f: F) -> Option<U>
where + F: FnOnce(&T) -> U,

Maps to Option<U> by applying a function to a dependency value (if Some) +or returns None (if None).

+
source

pub fn inspect<F>(&self, f: F) -> Option<&T>
where + F: FnOnce(&T),

Calls the provided closure with a reference to the dependency value (if Some).

+
source

pub fn map_or<U, F>(&self, default: U, f: F) -> U
where + F: FnOnce(&T) -> U,

Returns the provided default result (if None), +or applies a function to the dependency value (if Some).

+
source

pub fn map_or_else<U, D, F>(&self, default: D, f: F) -> U
where + D: FnOnce() -> U, + F: FnOnce(&T) -> U,

Computes a default function result (if None), or +applies a different function to the dependency value (if Some).

+
source

pub fn ok_or<E>(&self, err: E) -> Result<&T, E>

Transforms into a Result<&T, E>, mapping Some to +Ok and None to Err.

+
source

pub fn ok_or_else<E, F>(&self, err: F) -> Result<&T, E>
where + F: FnOnce() -> E,

Transforms into a Result<&T, E>, mapping Some to +Ok and None to Err.

+
source

pub fn as_deref(&self) -> Option<&T>

Converts into a Option<&T>.

+
§Note
+

This is the preferred method for producing an Option to use with the +question mark operator.1

+

  1. Once the Try trait is stabilized +it will be implemented for Dependency

source

pub fn and<U>(&self, rhs: Option<U>) -> Option<U>

Returns None if the dependency is None, otherwise returns rhs.

+
source

pub fn and_then<U, F: FnOnce(&T) -> Option<U>>(&self, f: F) -> Option<U>

Returns None if the dependency is None, otherwise calls f with the +dependency value and returns the result.

+
source

pub fn filter<P>(&self, predicate: P) -> Option<&T>
where + P: FnOnce(&T) -> bool,

Returns None if the dependency is None, otherwise calls predicate +with the dependency value and returns:

+
source

pub fn or(&self, rhs: Option<T>) -> Option<Ref<'_, T>>

Returns the dependency if it is Some, otherwise returns rhs.

+
source

pub fn or_else<F>(&self, f: F) -> Option<Ref<'_, T>>
where + F: FnOnce() -> Option<T>,

Returns the dependency if it is Some, otherwise calls f and returns the result.

+
source

pub fn xor(&self, rhs: Option<T>) -> Option<Ref<'_, T>>

Returns Some if only one of

+
    +
  • the dependency, or
  • +
  • rhs
  • +
+

is Some, otherwise returns None.

+
source

pub fn copied(&self) -> Option<T>
where + T: Copy,

Maps the dependency to an Option<T> by copying the contents of the option.

+
source

pub fn cloned(&self) -> Option<T>
where + T: Clone,

Maps the dependency to an Option<T> by cloning the contents of the option.

+
source§

impl<T: DependencyDefault> Dependency<T>

source

pub fn static_ref() -> &'static T

§SAFETY
+

A DependencyDefault, once fetched, will last for the life of the process.

+

Holding this reference is not advised as it will not reflect further overrides of this dependency.

+

Trait Implementations§

source§

impl<T: DependencyDefault> AsRef<T> for Dependency<T>

source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T: DependencyDefault> Borrow<T> for Dependency<T>

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> Default for Dependency<T>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<T: DependencyDefault> Deref for Dependency<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<T> !Freeze for Dependency<T>

§

impl<T> !RefUnwindSafe for Dependency<T>

§

impl<T> !Send for Dependency<T>

§

impl<T> !Sync for Dependency<T>

§

impl<T> Unpin for Dependency<T>

§

impl<T> UnwindSafe for Dependency<T>
where + T: RefUnwindSafe,

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/dependencies/trait.DependencyDefault.html b/composable/dependencies/trait.DependencyDefault.html new file mode 100644 index 00000000..ee6c386a --- /dev/null +++ b/composable/dependencies/trait.DependencyDefault.html @@ -0,0 +1,15 @@ +DependencyDefault in composable::dependencies - Rust

Trait composable::dependencies::DependencyDefault

source ·
pub trait DependencyDefault: Default { }
Expand description

The default value for a dependency.

+

There may be many different versions of dependencies for testing but there is often just +a single default implementation for use in the the actual application.

+

Implementing this trait for a type ensures that a Dependency on it will always have +a value. If the DependencyDefault value has not been overridden +it will be returned.

+
+Attempting to use this default behavior in a unit test will fail the test, +as tests are required to explicitly supply all of their dependencies. +
+

§Note

+

DependencyDefaults are only created as needed. When its first Dependency is +created, default will be called once and the returned value will +be cached.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T: DependencyDefault> DependencyDefault for Cell<T>

Implementors§

source§

impl DependencyDefault for Scale

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Values

Available on crate features unreleased and views only.
source§

impl DependencyDefault for Inter<'static, L>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, M>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, S>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, L>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, M>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, S>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, L>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, M>

Available on crate features unreleased and views and default_ui only.
source§

impl DependencyDefault for Inter<'static, S>

Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/dependencies/values/struct.Dependency.html b/composable/dependencies/values/struct.Dependency.html new file mode 100644 index 00000000..5a96ffb1 --- /dev/null +++ b/composable/dependencies/values/struct.Dependency.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/dependencies/struct.Dependency.html...

+ + + \ No newline at end of file diff --git a/composable/dependencies/values/trait.DependencyDefault.html b/composable/dependencies/values/trait.DependencyDefault.html new file mode 100644 index 00000000..ead3db80 --- /dev/null +++ b/composable/dependencies/values/trait.DependencyDefault.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/dependencies/trait.DependencyDefault.html...

+ + + \ No newline at end of file diff --git a/composable/derive_macros/derive.RecursiveReducer.html b/composable/derive_macros/derive.RecursiveReducer.html new file mode 100644 index 00000000..1804775f --- /dev/null +++ b/composable/derive_macros/derive.RecursiveReducer.html @@ -0,0 +1,51 @@ +RecursiveReducer in composable::derive_macros - Rust

Derive Macro composable::derive_macros::RecursiveReducer

#[derive(RecursiveReducer)]
+{
+    // Attributes available to this derive:
+    #[reducer]
+}
+
Expand description

§Compiler Errors

+

The are a few common mistakes that will produce well-known compiler errors

+

§the trait bound xxxx::State: composable::RecursiveReducer is not satisfied

| #[derive(RecursiveReducer)]
+|          ^^^^^^^^^^^^^^^^ the trait `composable::RecursiveReducer` is not implemented for `State`
+|
+= note: this error originates in the derive macro `RecursiveReducer`
+
+

Cause: You haven’t yet written an impl RecursiveReducer for the type you added #[derive(RecursiveReducer)] to.

+
+

§conflicting implementation for State

| #[derive(RecursiveReducer)]
+|          ^^^^^^^^^^^^^^^^ conflicting implementation for `State`
+...
+| impl Reducer for State {
+| ---------------------- first implementation here
+|
+= note: this error originates in the derive macro `RecursiveReducer`
+
+

Cause: You declared an impl Reducer, perhaps out of habit, rather than an impl RecursiveReducer.

+
+

§the trait bound …: composable::Reducer is not satisfied

| #[derive(RecursiveReducer)]
+|          ^^^^^^^^^^^^^^^^ the trait `composable::Reducer` is not implemented for `…`
+|
+= help: the following other types implement trait `composable::Reducer`:
+          ⋮
+= note: this error originates in the derive macro `RecursiveReducer`
+
+

where is replaced with the type of one of the struct’s fields in the error message.

+

Cause: A #[reducer(skip)] attribute is missing.

+
+

§type mismatch resolving <impl Effects<Action = Action> as Effects>::Action == Action

| #[derive(RecursiveReducer)]
+|          ^^^^^^^^^^^^^^^^ expected `child::Action`, found `parent::Action`
+|
+= note: `parent::Action` and `child::Action` have similar names, but are actually distinct types
+
+

Cause: … From

+
+

§the trait bound menu::Action: composable::From<winit::Action> is not satisfied

| #[derive(RecursiveReducer)]
+|          ^^^^^^^^^^^^^^^^ the trait `composable::From<parent::Action>` is not implemented for `child::Action`
+|
+
+

Cause: … TryInto

+
    +
  • Or there is no wrapper around a child action for the From macro to wrap a child action with
  • +
+
+
\ No newline at end of file diff --git a/composable/derive_macros/index.html b/composable/derive_macros/index.html new file mode 100644 index 00000000..264a915b --- /dev/null +++ b/composable/derive_macros/index.html @@ -0,0 +1,181 @@ +composable::derive_macros - Rust

Module composable::derive_macros

source ·
Expand description

Derive macros used to ease the creation of recursive reducers.

+
    +
  • RecursiveReducer
    +#[derive(RecursiveReducer)] on a enum or struct that contains other Reducer +types will derive a Reducer implementation for it.
  • +
  • TryInto
    +#[derive(TryInto)] on a Action whose variants contain another Reducer’s Actions +allows an attempted conversion to…
  • +
  • From
    +#[derive(TryInto)] on a Action whose variants contain another Reducer’s Actions +allows an attempted conversion from…
  • +
+

These macros produce efficient implementations of the Reducer, std::convert::TryInto +and std::convert::From traits so that they do not have to be implemented manually.

+
§Automatic Derived Reducers
+

Two other types are valid Reducers whenever they contain a Reducer.

+ +

These do not require the RecursiveReducer and automatically apply.

+

§Composite Reducers

+

A RecursiveReducer struct represents a parent-child relationship between Reducers. +This is the most common use of RecursiveReducer in large applications and forms the core +“Composability” of the Composable Architecture.

+

The application is broken up into different modules representing the different Domains or +Features of the application; each with its own Actions and State.

+

These Reducers are then collected into various composite Reducers that contain and +coordinate between them.

+

Each composite Reducer is written with the knowledge of its own Actions and the Actions +of its immediate children. The Actions of its parent are unknown to it and (by convention) it +does not traffic in the Actions of its grandchildren.

+

Deciding which Domains need to be coordinated between, and thus should be siblings under a +parent Domains, is the art of designing the application with an architecture like this one.

+

Even though the application struct recursively contains the States of all of it Features +it usually does not end up being very “tall.”

+

See Unidirectional Event Architecture for more.

+ +
mod A {
+    #[derive(Default)]
+    pub struct State { /* … */ }
+
+    #[derive(Clone)] // ⒈
+    pub enum Action { /* … */ }
+
+    impl Reducer for State {
+        type Action = Action;
+        type Output = Self;
+         
+        fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+            match action { /* … */ }
+        }
+    }
+}
+
+mod B {
+    #[derive(Default)]
+    pub struct State;
+
+    #[derive(Clone)] // ⒈
+    pub enum Action { /* … */ }
+
+    impl Reducer for State {
+        type Action = Action;
+        type Output = Self;
+
+        fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+            match action { /* … */ }
+        }
+    }
+}
+
+#[derive(Default, RecursiveReducer)] // ⒉
+struct State {
+    a: A::State,
+    b: B::State,
+}
+
+#[derive(Clone, From, TryInto)] // ⒊
+enum Action {
+    SomeAction, // parent actions
+    SomeOtherAction,
+
+    A(A::Action), // ⒋
+    B(B::Action),
+}
+
+impl RecursiveReducer for State { // ⒌
+    type Action = Action;
+
+    fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+        match action {
+            Action::SomeAction => { /* … */ }
+            Action::SomeOtherAction => { /* … */ }
+
+            // in this example, the parent reducer has
+            // no explicit handling of any child actions
+            _ => {}
+        }
+    }
+}
+
+
    +
  1. +

    Now that Actions are being passed to multiple Reducers they must be Clone.

    +
  2. +
  3. +

    The RecursiveReducer derive macro constructs a recursive Reducer from the struct.

    +
  4. +
  5. +

    The From and TryInfo derive macros ensure that conversions work, when they should, +between parent and child Actions. These conversions utilize #4…

    +
  6. +
  7. +

    The parent has one (and only one) Action for the Actions of each of its children.

    +
  8. +
  9. +

    Finally, an implementation of the RecursiveReducer trait containing the parent’s reduce +method. RecursiveReducer::reduce is run before the Reducer::reduce methods of its +fields. Resulting in:

    +
      +
    • self.reduce(), then
    • +
    • self.a.reduce(), then
    • +
    • self.b.reduce().
    • +
    +
  10. +
+

§Ignoring fields

+

Compound Reducers often contain fields other than the child Reducers. After all, it has +its own Reducer and that Reducer may need its own state.

+

The RecursiveReducer macro comes with an associated attribute that allows it to skip +struct members that should not ne made part of the Reducer recursion.

+ +
#[derive(RecursiveReducer)]
+struct State {
+    a: A::State,
+    b: B::State,
+
+    #[reducer(skip)]
+    c: Vec<u32>,
+}
+

§Alternate Reducers

+

A RecursiveReducer enum represents a single state that is best +represented by an enumeration a separate reducers.

+

Alternate Reducers are less common than Composite Reducers so a more concrete example may +help…

+ +
#[derive(RecursiveReducer)]
+enum State {
+    LoggedIn(authenticated::State),
+    LoggedOut(unauthenticated::State),
+}
+
+#[derive(Clone, From, TryInto)]
+enum Action {
+    LoggedIn(authenticated::Action),
+    LoggedOut(unauthenticated::Action),
+}
+
+impl RecursiveReducer for State {
+    type Action = Action;
+
+    fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+        // logic independent of the user’s authentication
+    }
+}
+

authenticated::Actions will only run when the state is LoggedIn and vice-versa..

+
+
+

Now, the automatic derive reducer behavior of Option is easy to described. +It behaves is as if it were:

+ +
#[derive(RecursiveReducer)]
+enum Option<T: Reducer> {
+    #[reducer(skip)]
+    None,
+    Some(T),
+}
+

Although, currently, the RecursiveReducer macro does not work with generic parameters on the +type it is attempting to derive the Reducer trait for.

+

Re-exports§

  • pub use derive_more::From;
  • pub use derive_more::TryInto;

Traits§

Derive Macros§

\ No newline at end of file diff --git a/composable/derive_macros/sidebar-items.js b/composable/derive_macros/sidebar-items.js new file mode 100644 index 00000000..02e8f0aa --- /dev/null +++ b/composable/derive_macros/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"derive":["RecursiveReducer"],"trait":["RecursiveReducer"]}; \ No newline at end of file diff --git a/composable/derive_macros/trait.RecursiveReducer.html b/composable/derive_macros/trait.RecursiveReducer.html new file mode 100644 index 00000000..8855dae8 --- /dev/null +++ b/composable/derive_macros/trait.RecursiveReducer.html @@ -0,0 +1,15 @@ +RecursiveReducer in composable::derive_macros - Rust

Trait composable::derive_macros::RecursiveReducer

source ·
pub trait RecursiveReducer {
+    type Action;
+
+    // Required method
+    fn reduce(
+        &mut self,
+        action: Self::Action,
+        effects: impl Effects<Self::Action>,
+    );
+}
Expand description

See the RecursiveReducer macro for example usage.

+

Required Associated Types§

source

type Action

All of the possible actions that can be used to modify state. +Equivalent to Reducer::Action.

+

Required Methods§

source

fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>)

This reduce should perform any actions that are needed before the macro recurses +into the other reducers.

+

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/composable/effects/enum.Interval.html b/composable/effects/enum.Interval.html new file mode 100644 index 00000000..15308449 --- /dev/null +++ b/composable/effects/enum.Interval.html @@ -0,0 +1,18 @@ +Interval in composable::effects - Rust

Enum composable::effects::Interval

source ·
pub enum Interval {
+    Leading(Duration),
+    Trailing(Duration),
+}
Expand description

When a Scheduler uses a repeating interval, that interval can begin immediately, a Leading +interval, or it may begin after the first delay, a Trailing interval.

+

Variants§

§

Leading(Duration)

The first Action should be sent immediately.

+
§

Trailing(Duration)

The first Action should not be send until after the Duration has passed.

+

Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/effects/index.html b/composable/effects/index.html new file mode 100644 index 00000000..a56ebe1d --- /dev/null +++ b/composable/effects/index.html @@ -0,0 +1,3 @@ +composable::effects - Rust

Module composable::effects

source ·
Expand description

Additional work to be done after performing an action.

+

Structs§

  • An Effects that scopes its Actions to one that sends child actions.

Enums§

  • When a Scheduler uses a repeating interval, that interval can begin immediately, a Leading +interval, or it may begin after the first delay, a Trailing interval.

Traits§

  • Effects are used within Reducers to propagate Actions as side-effects of performing other Actions.
  • Effects are also Schedulers — able to apply modifiers to when (and how often) Actions. are sent.
\ No newline at end of file diff --git a/composable/effects/sidebar-items.js b/composable/effects/sidebar-items.js new file mode 100644 index 00000000..8c80abae --- /dev/null +++ b/composable/effects/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Interval"],"struct":["Scoped"],"trait":["Effects","Scheduler"]}; \ No newline at end of file diff --git a/composable/effects/struct.Scoped.html b/composable/effects/struct.Scoped.html new file mode 100644 index 00000000..2faa9db0 --- /dev/null +++ b/composable/effects/struct.Scoped.html @@ -0,0 +1,45 @@ +Scoped in composable::effects - Rust

Struct composable::effects::Scoped

source ·
pub struct Scoped<Parent, Child>(/* private fields */);
Expand description

An Effects that scopes its Actions to one that sends child actions.

+

This struct is created by the scope method on Effects. See its +documentation for more.

+

Trait Implementations§

source§

impl<Parent: Clone, Child> Clone for Scoped<Parent, Child>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<Parent, Child> Effects for Scoped<Parent, Child>
where + Parent: Effects, + <Parent as Effects>::Action: Clone + From<Child> + 'static, + Child: 'static,

§

type Action = Child

The Action type sent by this Effects.
source§

fn send(&self, action: impl Into<<Self as Effects>::Action>)

An effect that immediately sends an Action through +the Store’s Reducer.
source§

fn task<S: Stream<Item = Child> + 'static>(&self, stream: S) -> Task

A Task represents asynchronous work that will then send +zero or more Actions back into the Store’s Reducer +as it runs. Read more
source§

fn future<F: Future<Output = Option<<Self as Effects>::Action>> + 'static>( + &self, + future: F, +)
where + <Self as Effects>::Action: 'static,

An effect that runs a Future and, if it returns an +Action, sends it through the Store’s Reducer.
source§

fn stream<S: Stream<Item = <Self as Effects>::Action> + 'static>( + &self, + stream: S, +)

An effect that runs a Stream +and sends every Action it returns through the Store’s +Reducer.
source§

fn scope<ChildAction>(&self) -> Scoped<Self, ChildAction>
where + <Self as Effects>::Action: From<ChildAction>,

Scopes the Effects down to one that sends child actions. Read more

Auto Trait Implementations§

§

impl<Parent, Child> Freeze for Scoped<Parent, Child>
where + Parent: Freeze,

§

impl<Parent, Child> RefUnwindSafe for Scoped<Parent, Child>
where + Parent: RefUnwindSafe, + Child: RefUnwindSafe,

§

impl<Parent, Child> Send for Scoped<Parent, Child>
where + Parent: Send, + Child: Send,

§

impl<Parent, Child> Sync for Scoped<Parent, Child>
where + Parent: Sync, + Child: Sync,

§

impl<Parent, Child> Unpin for Scoped<Parent, Child>
where + Parent: Unpin, + Child: Unpin,

§

impl<Parent, Child> UnwindSafe for Scoped<Parent, Child>
where + Parent: UnwindSafe, + Child: UnwindSafe,

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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, Action> Effects<Action> for T
where + T: Effects<Action = Action> + 'static,

\ No newline at end of file diff --git a/composable/effects/trait.Effects.html b/composable/effects/trait.Effects.html new file mode 100644 index 00000000..937524a6 --- /dev/null +++ b/composable/effects/trait.Effects.html @@ -0,0 +1,66 @@ +Effects in composable::effects - Rust

Trait composable::effects::Effects

source ·
pub trait Effects: Clone + Scheduler<Action = Self::Action> {
+    type Action;
+
+    // Required methods
+    fn send(&self, action: impl Into<<Self as Effects>::Action>);
+    fn task<S: Stream<Item = <Self as Effects>::Action> + 'static>(
+        &self,
+        stream: S,
+    ) -> Task;
+
+    // Provided methods
+    fn future<F: Future<Output = Option<<Self as Effects>::Action>> + 'static>(
+        &self,
+        future: F,
+    )
+       where <Self as Effects>::Action: 'static { ... }
+    fn stream<S: Stream<Item = <Self as Effects>::Action> + 'static>(
+        &self,
+        stream: S,
+    ) { ... }
+    fn scope<ChildAction>(&self) -> Scoped<Self, ChildAction>
+       where <Self as Effects>::Action: From<ChildAction> { ... }
+}
Expand description

Effects are used within Reducers to propagate Actions as side-effects of performing other Actions.

+

Effects are also Schedulers — able to apply modifiers to when (and how often) Actions. are sent.

+

See the module level documentation for more.

+

Required Associated Types§

source

type Action

The Action type sent by this Effects.

+

Required Methods§

source

fn send(&self, action: impl Into<<Self as Effects>::Action>)

An effect that immediately sends an Action through +the Store’s Reducer.

+
source

fn task<S: Stream<Item = <Self as Effects>::Action> + 'static>( + &self, + stream: S, +) -> Task

A Task represents asynchronous work that will then send +zero or more Actions back into the Store’s Reducer +as it runs.

+

Use this method if you need to ability to cancel the task +while it is running. Otherwise future or stream +should be preferred.

+

Provided Methods§

source

fn future<F: Future<Output = Option<<Self as Effects>::Action>> + 'static>( + &self, + future: F, +)
where + <Self as Effects>::Action: 'static,

An effect that runs a Future and, if it returns an +Action, sends it through the Store’s Reducer.

+
source

fn stream<S: Stream<Item = <Self as Effects>::Action> + 'static>( + &self, + stream: S, +)

An effect that runs a Stream +and sends every Action it returns through the Store’s +Reducer.

+
source

fn scope<ChildAction>(&self) -> Scoped<Self, ChildAction>
where + <Self as Effects>::Action: From<ChildAction>,

Scopes the Effects down to one that sends child actions.

+

For example, the inner loop of the RecursiveReducer macro is, +effectively, just calling

+ +
if let Ok(action) = action.clone().try_into() {
+    reduce(&mut self.child_reducer, action, effects.scope());
+}
+

on each child-reducer.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<Action> Effects for Rc<RefCell<Inner<Action>>>
where + Action: Debug + 'static,

§

type Action = Action

source§

fn send(&self, action: impl Into<<Self as Effects>::Action>)

source§

fn task<S: Stream<Item = <Self as Effects>::Action> + 'static>( + &self, + stream: S, +) -> Task

Implementors§

source§

impl<Parent, Child> Effects for Scoped<Parent, Child>
where + Parent: Effects, + <Parent as Effects>::Action: Clone + From<Child> + 'static, + Child: 'static,

§

type Action = Child

\ No newline at end of file diff --git a/composable/effects/trait.Scheduler.html b/composable/effects/trait.Scheduler.html new file mode 100644 index 00000000..8365f24e --- /dev/null +++ b/composable/effects/trait.Scheduler.html @@ -0,0 +1,61 @@ +Scheduler in composable::effects - Rust

Trait composable::effects::Scheduler

source ·
pub trait Scheduler {
+    type Action;
+
+    // Provided methods
+    fn after(&self, duration: Duration, action: Self::Action) -> Task
+       where Self::Action: Clone + 'static { ... }
+    fn at(&self, instant: Instant, action: Self::Action) -> Task
+       where Self::Action: Clone + 'static { ... }
+    fn every(&self, interval: Interval, action: Self::Action) -> Task
+       where Self::Action: Clone + 'static { ... }
+    fn debounce(
+        &self,
+        action: Self::Action,
+        previous: &mut Option<Task>,
+        interval: Interval,
+    )
+       where Self::Action: Clone + 'static { ... }
+    fn throttle(
+        &self,
+        action: Self::Action,
+        previous: &mut Option<Task>,
+        interval: Interval,
+    )
+       where Self::Action: Clone + 'static { ... }
+}
Expand description

Effects are also Schedulers — able to apply modifiers to when (and how often) Actions. are sent.

+

Required Associated Types§

source

type Action

The Action sends scheduled by this Scheduler.

+

Provided Methods§

source

fn after(&self, duration: Duration, action: Self::Action) -> Task
where + Self::Action: Clone + 'static,

Sends the Action after duration.

+
source

fn at(&self, instant: Instant, action: Self::Action) -> Task
where + Self::Action: Clone + 'static,

Sends the Action at instant.

+
source

fn every(&self, interval: Interval, action: Self::Action) -> Task
where + Self::Action: Clone + 'static,

Sends the Action every interval.

+
source

fn debounce( + &self, + action: Self::Action, + previous: &mut Option<Task>, + interval: Interval, +)
where + Self::Action: Clone + 'static,

An effect that coalesces repeated attempts to send Actions +through the Store’s Reducer into a singe send. +Once timeout has elapsed with no further Actions being attempted, +the last Action will be sent.

+

The debounce function will automatically update the information +stored in previous as it runs. The Task debounced by this call +will be the previous task for the next call, if any.

+
source

fn throttle( + &self, + action: Self::Action, + previous: &mut Option<Task>, + interval: Interval, +)
where + Self::Action: Clone + 'static,

An effect that sends an Action through the Store’s +Reducer if at least one interval of time has passed +since previous was sent. Otherwise, all subsequent actions but the last +are dropped until that time; which resets the countdown until the next +debounced action can be sent.

+

The throttle function will automatically update the information +stored in previous as it runs. The Task throttled by this call +will be the previous task for the next call, if any.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<Action> Scheduler for Rc<RefCell<Inner<Action>>>
where + Action: Debug + 'static,

§

type Action = Action

Implementors§

\ No newline at end of file diff --git a/composable/enum.Interval.html b/composable/enum.Interval.html new file mode 100644 index 00000000..ebada61d --- /dev/null +++ b/composable/enum.Interval.html @@ -0,0 +1,18 @@ +Interval in composable - Rust

Enum composable::Interval

source ·
pub enum Interval {
+    Leading(Duration),
+    Trailing(Duration),
+}
Expand description

When a Scheduler uses a repeating interval, that interval can begin immediately, a Leading +interval, or it may begin after the first delay, a Trailing interval.

+

Variants§

§

Leading(Duration)

The first Action should be sent immediately.

+
§

Trailing(Duration)

The first Action should not be send until after the Duration has passed.

+

Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/index.html b/composable/index.html new file mode 100644 index 00000000..79952891 --- /dev/null +++ b/composable/index.html @@ -0,0 +1,82 @@ +composable - Rust

Crate composable

source ·
Expand description

§A Composable Architecture

+

The Swift Composable Architecture library improves upon previous Redux-inspired patterns by leveraging the capabilities of the Swift language to achieve better Type Safety, Ergonomics and Performance.

+

This crate attempts to do the same to the Swift Composable Architecture itself by further leveraging the capabilities of the Rust language and ecosystem.

+
+What is the Swift Composable Architecture? +
+

The Composable Architecture (TCA, for short) is a library for building applications in a consistent and understandable way, with composition, testing, and ergonomics in mind. It can be used in SwiftUI, UIKit, and more, and on any Apple platform (iOS, macOS, tvOS, and watchOS).

+

Learn More

+

The Composable Architecture was designed over the course of many episodes on Point•Free, a video series exploring functional programming and the Swift language, hosted by Brandon Williams and Stephen Celis.

+

You can watch all of the episodes here, as well as a dedicated, multipart tour of the architecture from scratch: part 1, part 2, part 3 and part 4.

+

+
+
+

The API has diverged to better reflect the different strengths (and weaknesses) of Rust and Swift, but the core ideals are the same.

+
    +
  • +

    State management

    +

    Using States and Reducers to manage Rust’s restrictions on Variables and Mutability

    +
  • +
  • +

    Composition

    +
  • +
  • +

    Side effects

    +
  • +
  • +

    Testing

    +
  • +
  • +

    Ergonomics

    +
  • +
+

§License

+

Distributed under the terms of both the MIT license and the Apache License (Version 2.0)

+

See LICENSE-APACHE and LICENSE-MIT for details.

+

§Contribution

+

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

+

§Why use Composable?

+

A composable architecture is based around

+
+

§Note

+

If you have already used another unidirectional data flow architecture for application state management, the main take-away is that the State-Reducer pattern is a great fit to Rust’s restrictions on Variables and Mutability:

+
    +
  • Rust requires mutable references to be unique
  • +
  • State mutations may only happen within a Reducer
  • +
+
+

As for this crate specifically. Features include:

+
    +
  • +

    Small

    +

    The core functionality is under 2000 lines of code and has minimal dependancies.1

    +
  • +
  • +

    Fast

    +

    Store::send takes less than 20 nanoseconds.
    +Effects are 5–10× faster.

    +
  • +
  • +

    Reliable

    +

    No unsafe code.

    +
  • +
+

Furthermore, the optional async handling is done without dependence on a runtime. A Store runs its Reducer entirely within a single thread. At the same time, Effects make it easy for an application to run code, concurrently or in parallel, that feeds its results back into the appropriate Reducer.

+

§Usage

+

To use Composable, place the following line under the [dependencies] section in your Cargo.toml:

+
composable = "x.y"
+

§Optional Features

+
+
    +
  • +

    unreleased: enable features that are still heavily under development. Unreleased features include:

    + +

    Note that changes to unreleased: code will never be considered a semver breaking change.

    +
  • +
+

  1. As counted with tokei --exclude src/views/ --exclude examples --exclude benches

Re-exports§

Modules§

  • Ergonomic dependency handling.
  • Derive macros used to ease the creation of recursive reducers.
  • Additional work to be done after performing an action.
  • viewsunreleased and views
    Optional view feature.

Structs§

  • The state container for the application.
  • Asynchronous work being performed by a Store.
  • A state container for the application testing.

Enums§

  • When a Scheduler uses a repeating interval, that interval can begin immediately, a Leading +interval, or it may begin after the first delay, a Trailing interval.

Traits§

  • Effects are used within Reducers to propagate Actions as side-effects of performing other +Actions.
  • Reducers are responsible for updating a Store’s state in response to its Actions.
  • When testing, it is important to have control over the (simulated) passage of time.
\ No newline at end of file diff --git a/composable/reducer/trait.Reducer.html b/composable/reducer/trait.Reducer.html new file mode 100644 index 00000000..21ee9d3e --- /dev/null +++ b/composable/reducer/trait.Reducer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../composable/trait.Reducer.html...

+ + + \ No newline at end of file diff --git a/composable/sidebar-items.js b/composable/sidebar-items.js new file mode 100644 index 00000000..0e370013 --- /dev/null +++ b/composable/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Interval"],"mod":["dependencies","derive_macros","effects","views"],"struct":["Store","Task","TestStore"],"trait":["Effects","Reducer","TestClock"]}; \ No newline at end of file diff --git a/composable/store/struct.Store.html b/composable/store/struct.Store.html new file mode 100644 index 00000000..732e0740 --- /dev/null +++ b/composable/store/struct.Store.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../composable/struct.Store.html...

+ + + \ No newline at end of file diff --git a/composable/store/testing/clock/trait.TestClock.html b/composable/store/testing/clock/trait.TestClock.html new file mode 100644 index 00000000..9aa509d5 --- /dev/null +++ b/composable/store/testing/clock/trait.TestClock.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/trait.TestClock.html...

+ + + \ No newline at end of file diff --git a/composable/store/testing/struct.TestStore.html b/composable/store/testing/struct.TestStore.html new file mode 100644 index 00000000..fb571b6a --- /dev/null +++ b/composable/store/testing/struct.TestStore.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/struct.TestStore.html...

+ + + \ No newline at end of file diff --git a/composable/struct.Store.html b/composable/struct.Store.html new file mode 100644 index 00000000..ae2e3e66 --- /dev/null +++ b/composable/struct.Store.html @@ -0,0 +1,36 @@ +Store in composable - Rust

Struct composable::Store

source ·
pub struct Store<State: Reducer> { /* private fields */ }
Expand description

The state container for the application.

+

§Threading

Implementations§

source§

impl<State: Reducer> Store<State>

source

pub fn with_initial(state: State) -> Self
where + State: Send + 'static, + <State as Reducer>::Action: Send, + <State as Reducer>::Output: Send + From<State>,

Creates a new Store with state as its initial state.

+

If State is not Send, then new or default +can be used instead.

+
source

pub fn new<F>(with: F) -> Self
where + F: FnOnce() -> State + Send + 'static, + <State as Reducer>::Action: Send + 'static, + <State as Reducer>::Output: Send + From<State> + 'static,

Creates a new Store with its initial state generated by a function.

+

Useful if State is not Send, but the arguments used to construct it are.

+
source

pub fn send(&self, action: impl Into<<State as Reducer>::Action>)

Calls the Store’s Reducer with action.

+

Takes an Into<Action> so that both child and parent Actions may be sent easily.

+
source

pub fn into_inner(self) -> <State as Reducer>::Output

Stops the Store’s runtime and returns its current state value.

+
§Note
+

Care should be exercised when using this method in applications that utilize +asynchronous Effects. into_inner makes a “best effort” +to wait until any pending tasks are completed but it is not guaranteed.

+

Trait Implementations§

source§

impl<State> Default for Store<State>
where + State: Default + Reducer, + <State as Reducer>::Action: Send + 'static, + <State as Reducer>::Output: Send + From<State> + 'static,

source§

fn default() -> Self

Creates a new Store with a default initial state.

+

Auto Trait Implementations§

§

impl<State> Freeze for Store<State>

§

impl<State> !RefUnwindSafe for Store<State>

§

impl<State> Send for Store<State>
where + <State as Reducer>::Action: Send,

§

impl<State> Sync for Store<State>
where + <State as Reducer>::Action: Send,

§

impl<State> Unpin for Store<State>

§

impl<State> !UnwindSafe for Store<State>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/struct.Task.html b/composable/struct.Task.html new file mode 100644 index 00000000..b917f810 --- /dev/null +++ b/composable/struct.Task.html @@ -0,0 +1,5 @@ +Task in composable - Rust

Struct composable::Task

source ·
pub struct Task { /* private fields */ }
Expand description

Asynchronous work being performed by a Store.

+

A Store uses a Local Async Executor to run its Tasks.

+

Implementations§

source§

impl Task

source

pub fn detach(self)

Detaches the task; leaving its Future running in the background.

+
source

pub fn cancel(self)

Cancels the task; meaning its Future won’t be polled again.

+
\ No newline at end of file diff --git a/composable/struct.TestStore.html b/composable/struct.TestStore.html new file mode 100644 index 00000000..c791062c --- /dev/null +++ b/composable/struct.TestStore.html @@ -0,0 +1,99 @@ +TestStore in composable - Rust

Struct composable::TestStore

source ·
pub struct TestStore<State: Reducer>
where + <State as Reducer>::Action: Debug,
{ /* private fields */ }
Expand description

A state container for the application testing.

+

§Example

+

Here is the second Reducer example being tested with a TestStore.

+ +
#[derive(Clone, Debug, Default, PartialEq)]
+struct State {
+    n: usize,
+}
+
+#[derive(Debug, PartialEq)]
+enum Action {
+    Increment,
+    Decrement,
+}
+
+use Action::*;
+impl Reducer for State {
+    type Action = Action;
+    type Output = Self;
+
+    // This reducer ensures the value is always an even number
+    fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+        match action {
+            Increment => {
+                self.n += 1;
+                if self.n % 2 == 1 {
+                    effects.send(Increment);
+                }
+            }
+            Decrement => {
+                self.n -= 1;
+                if self.n % 2 == 1 {
+                    effects.send(Decrement);
+                }
+            }
+        }
+    }
+}
+
+let mut store = TestStore::<State>::default();
+
+store.send(Increment, |state| state.n = 1);
+store.recv(Increment, |state| state.n = 2);
+
+store.send(Increment, |state| state.n = 3);
+store.recv(Increment, |state| state.n = 4);
+
+store.send(Decrement, |state| state.n = 3);
+store.recv(Decrement, |state| state.n = 2);
+
+let n = store.into_inner().n;
+assert_eq!(n, 2);
+

Implementations§

source§

impl<State: Reducer> TestStore<State>
where + <State as Reducer>::Action: Debug,

source

pub fn new<F>(with: F) -> Self
where + F: FnOnce() -> State,

Creates a new Store with its initial state generated by a function.

+
source

pub fn with_initial(state: State) -> Self

Creates a new Store with state as its initial state.

+
source

pub fn send( + &mut self, + action: <State as Reducer>::Action, + assert: impl FnOnce(&mut State), +)
where + State: Clone + Debug + PartialEq, + <State as Reducer>::Action: 'static,

Calls the Store’s Reducer with action and asserts the +expected state changes.

+
source

pub fn recv( + &mut self, + action: <State as Reducer>::Action, + assert: impl FnOnce(&mut State), +)
where + State: Clone + Debug + PartialEq, + <State as Reducer>::Action: Debug + PartialEq + 'static,

Checks that the Store’s Reducer was called with action +and asserts the expected state changes.

+
source

pub fn wait(&mut self)

Waits until all scheduled tasks have completed.

+

A timeout should be added to tests calling wait() to ensure that it +does not wait forever if there are bugs in the asynchronous tasks. +For example

+ +
source

pub fn into_inner(self) -> <State as Reducer>::Output
where + State: Into<<State as Reducer>::Output>,

Consumes the Store and returns its current state value.

+

Trait Implementations§

source§

impl<State> Default for TestStore<State>
where + State: Default + Reducer, + <State as Reducer>::Action: Debug,

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<State: Reducer> Drop for TestStore<State>
where + <State as Reducer>::Action: Debug,

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<State: Reducer> TestClock for TestStore<State>
where + <State as Reducer>::Action: Debug,

source§

fn advance(&mut self, duration: Duration)

Auto Trait Implementations§

§

impl<State> !Freeze for TestStore<State>

§

impl<State> !RefUnwindSafe for TestStore<State>

§

impl<State> !Send for TestStore<State>

§

impl<State> !Sync for TestStore<State>

§

impl<State> Unpin for TestStore<State>
where + State: Unpin,

§

impl<State> !UnwindSafe for TestStore<State>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/trait.Effects.html b/composable/trait.Effects.html new file mode 100644 index 00000000..e517792d --- /dev/null +++ b/composable/trait.Effects.html @@ -0,0 +1,9 @@ +Effects in composable - Rust

Trait composable::Effects

source ·
pub trait Effects<Action>: Effects<Action = Action> + 'static { }
Expand description

Effects are used within Reducers to propagate Actions as side-effects of performing other +Actions.

+

Effects are also Schedulers — able to apply modifiers to when (and how often) Actions. are sent.

+

This is a “trait alias” (to the actual Effects trait) to simplify +Reducer signatures and set the lifetime to 'static.

+

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<T, Action> Effects<Action> for T
where + T: Effects<Action = Action> + 'static,

Until actual trait aliases are stabilized this work around allows the trait shown above +to be used anywhere that the original trait can.

+
\ No newline at end of file diff --git a/composable/trait.Reducer.html b/composable/trait.Reducer.html new file mode 100644 index 00000000..39e05ece --- /dev/null +++ b/composable/trait.Reducer.html @@ -0,0 +1,108 @@ +Reducer in composable - Rust

Trait composable::Reducer

source ·
pub trait Reducer {
+    type Action;
+    type Output;
+
+    // Required method
+    fn reduce(
+        &mut self,
+        action: Self::Action,
+        effects: impl Effects<Self::Action>,
+    );
+}
Expand description

Reducers are responsible for updating a Store’s state in response to its Actions.

+

Required Associated Types§

source

type Action

All of the possible actions that can be used to modify state.

+
source

type Output

Both unit tests and command line applications often need to return their Store’s final +state. Therefore Store’s into_inner method shuts down the Store and converts its +Reducer into its Output type.

+

Using a separate Output type, rather than returning the Reducer itself, allows the +Stores to support Reducer types that are not Send.

+
    +
  • Reducers that do not need to support into_inner should use declare +type Output = Self; as it is a simple, recognizable default.
  • +
  • A Reducer that is Send can also default to type Output = Self;.
  • +
  • Otherwise, the Reducer will need to declare an Output type that is Send and +that can be crated From the Reducer’s state.
  • +
+ +
struct State {
+    n: Rc<Cell<usize>>, // Rc<Cell<…>> is not Send
+};
+
+enum Action { /* … */ }
+
+impl Reducer for State {
+    type Action = Action;
+    type Output = usize; // but the usize itself _is_
+
+    fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>) { /**/ }
+}
+
+impl From<State> for usize {
+    fn from(value: State) -> Self {
+        Cell::into_inner(Rc::into_inner(value.n).unwrap_or_default())
+    }
+}
+

In short, you can use type Output = Self; until the compiler says that you can’t.

+

Required Methods§

source

fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>)

Updates the Reducer’s state in response to the action received.

+

Additional Actions that need to be performed as a side-effect of an Action should be +invoked on effects. +The logic of the feature is performed by mutating its current State with Actions.

+ +
#[derive(Clone, Debug, Default, PartialEq)]
+struct State {
+    n: usize,
+}
+
+#[derive(Debug, PartialEq)]
+enum Action {
+    Increment,
+    Decrement,
+}
+

This is most easily done by implementing the Reducer trait directly on it’s State.

+ +
use Action::*;
+impl Reducer for State {
+    type Action = Action;
+    type Output = usize;
+
+    fn reduce(&mut self, action: Action, _effects: impl Effects<Action>) {
+        match action {
+            Increment => {
+                self.n += 1;
+            }
+            Decrement => {
+                self.n -= 1;
+            }
+        }
+    }
+}
+

The reduce method’s first responsibility is to mutate the feature’s current state given an action. Its second responsibility is to trigger effects that feed their actions back into the system. Currently reduce does not need to run any effects so _effects goes unused.

+

If the action does need side effects, then more would need to be done. For example, if reduce always maintained an even number for the State, then each Increment and Decrement would need an effect to follow:1

+ +
use Action::*;
+impl Reducer for State {
+    type Action = Action;
+    type Output = usize;
+
+    // This reducer ensures the value is always an even number
+    fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+        match action {
+            Increment => {
+                self.n += 1;
+                if self.n % 2 == 1 {
+                    effects.send(Increment); // ⬅︎
+                }
+            }
+            Decrement => {
+                self.n -= 1;
+                if self.n % 2 == 1 {
+                    effects.send(Decrement); // ⬅︎
+                }
+            }
+        }
+    }
+}
+
    +
  • See TestStore for a more complete test of this example.
  • +
  • See Effects for all of the effects that can be used within a Reducer.
  • +
+

  1. Granted, real code could just adjust the values by two. It is a contrived example to show how to use effects, after all. 

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T: Reducer> Reducer for Option<T>

§

type Action = <T as Reducer>::Action

§

type Output = Option<<T as Reducer>::Output>

source§

fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>)

source§

impl<T: Reducer> Reducer for Box<T>

§

type Action = <T as Reducer>::Action

§

type Output = <T as Reducer>::Output

source§

fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>)

Implementors§

\ No newline at end of file diff --git a/composable/trait.TestClock.html b/composable/trait.TestClock.html new file mode 100644 index 00000000..9c34ae68 --- /dev/null +++ b/composable/trait.TestClock.html @@ -0,0 +1,58 @@ +TestClock in composable - Rust

Trait composable::TestClock

source ·
pub trait TestClock {
+    // Required method
+    fn advance(&mut self, duration: Duration);
+}
Expand description

When testing, it is important to have control over the (simulated) passage of time.

+

+ +
#[derive(Clone, Debug, Default)]
+ struct State {
+     previous: Option<Task>,
+     n: usize,
+ }
+
+#[derive(Clone, Debug, PartialEq)]
+enum Action {
+    Send,
+    Recv,
+}
+
+use Action::*;
+
+impl Reducer for State {
+    type Action = Action;
+    type Output = Self;
+
+    fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+        match action {
+            Send => {
+                effects.debounce(
+                    Recv,
+                    &mut self.previous,
+                    Interval::Trailing(Duration::from_secs(4)),
+                );
+            }
+            Recv => {
+                self.n += 1;
+            }
+        }
+    }
+}
+
+let mut store = TestStore::<State>::default();
+let no_change: fn(&mut State) = |State| {};
+
+store.send(Send, no_change);
+store.advance(Duration::from_secs(3));
+
+store.send(Send, no_change);
+store.advance(Duration::from_secs(8));
+store.recv(Recv, |state| state.n = 1);
+
+store.send(Send, no_change);
+store.advance(Duration::from_secs(1));
+store.advance(Duration::from_secs(1));
+store.advance(Duration::from_secs(1));
+store.advance(Duration::from_secs(1));
+store.recv(Recv, |state| state.n = 2);
+

Required Methods§

source

fn advance(&mut self, duration: Duration)

Implementors§

source§

impl<State: Reducer> TestClock for TestStore<State>
where + <State as Reducer>::Action: Debug,

\ No newline at end of file diff --git a/composable/views/enum.Event.html b/composable/views/enum.Event.html new file mode 100644 index 00000000..7eb9cab5 --- /dev/null +++ b/composable/views/enum.Event.html @@ -0,0 +1,22 @@ +Event in composable::views - Rust

Enum composable::views::Event

source ·
pub enum Event {
+    Gesture(Gesture),
+    Resize {
+        width: u32,
+        height: u32,
+    },
+    Redraw,
+}
Available on crate features unreleased and views only.
Expand description

View events.

+

Variants§

§

Gesture(Gesture)

§

Resize

Fields

§width: u32
§height: u32
§

Redraw

Trait Implementations§

source§

impl Clone for Event

source§

fn clone(&self) -> Event

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl From<()> for Event

source§

fn from(original: ()) -> Event

Converts to this type from the input type.
source§

impl From<(u32, u32)> for Event

source§

fn from(original: (u32, u32)) -> Event

Converts to this type from the input type.
source§

impl From<Gesture> for Event

source§

fn from(original: Gesture) -> Event

Converts to this type from the input type.
source§

impl TryFrom<Event> for ()

§

type Error = &'static str

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

fn try_from(value: Event) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Event> for (u32, u32)

§

type Error = &'static str

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

fn try_from(value: Event) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryFrom<Event> for Gesture

§

type Error = &'static str

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

fn try_from(value: Event) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Copy for Event

Auto Trait Implementations§

§

impl Freeze for Event

§

impl RefUnwindSafe for Event

§

impl Send for Event

§

impl Sync for Event

§

impl Unpin for Event

§

impl UnwindSafe for Event

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/enum.Gesture.html b/composable/views/enum.Gesture.html new file mode 100644 index 00000000..f6da8b20 --- /dev/null +++ b/composable/views/enum.Gesture.html @@ -0,0 +1,25 @@ +Gesture in composable::views - Rust

Enum composable::views::Gesture

source ·
pub enum Gesture {
+    Began {
+        n: u8,
+    },
+    Moved {
+        n: u8,
+    },
+    Ended {
+        n: u8,
+    },
+}
Available on crate features unreleased and views only.
Expand description

touches… buttons…

+

Variants§

§

Began

Fields

§n: u8
§

Moved

Fields

§n: u8
§

Ended

Fields

§n: u8

Trait Implementations§

source§

impl Clone for Gesture

source§

fn clone(&self) -> Gesture

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl From<Gesture> for Event

source§

fn from(original: Gesture) -> Event

Converts to this type from the input type.
source§

impl TryFrom<Event> for Gesture

§

type Error = &'static str

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

fn try_from(value: Event) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Copy for Gesture

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/gesture/enum.Response.html b/composable/views/gesture/enum.Response.html new file mode 100644 index 00000000..15457a63 --- /dev/null +++ b/composable/views/gesture/enum.Response.html @@ -0,0 +1,24 @@ +Response in composable::views::gesture - Rust

Enum composable::views::gesture::Response

source ·
pub enum Response {
+    DownInside,
+    UpInside,
+    UpOutside,
+    DragInside,
+    DragExit,
+    DragOutside,
+    DragEnter,
+}
Available on crate features unreleased and views only.

Variants§

§

DownInside

§

UpInside

§

UpOutside

§

DragInside

§

DragExit

§

DragOutside

§

DragEnter

Trait Implementations§

source§

impl Clone for Response

source§

fn clone(&self) -> Response

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Response

source§

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

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

impl PartialEq for Response

source§

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

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Response

source§

impl Eq for Response

source§

impl StructuralPartialEq for Response

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/gesture/fn.recognizer.html b/composable/views/gesture/fn.recognizer.html new file mode 100644 index 00000000..6d417e71 --- /dev/null +++ b/composable/views/gesture/fn.recognizer.html @@ -0,0 +1,6 @@ +recognizer in composable::views::gesture - Rust

Function composable::views::gesture::recognizer

source ·
pub fn recognizer(
+    id: Id,
+    gesture: Gesture,
+    location: Point,
+    bounds: Bounds,
+) -> Option<Response>
Available on crate features unreleased and views only.
Expand description
\ No newline at end of file diff --git a/composable/views/gesture/index.html b/composable/views/gesture/index.html new file mode 100644 index 00000000..95da912f --- /dev/null +++ b/composable/views/gesture/index.html @@ -0,0 +1 @@ +composable::views::gesture - Rust

Module composable::views::gesture

source ·
Available on crate features unreleased and views only.

Structs§

Enums§

Functions§

Type Aliases§

  • The user interface state carried between cycles by the application.
\ No newline at end of file diff --git a/composable/views/gesture/recognizer/enum.Response.html b/composable/views/gesture/recognizer/enum.Response.html new file mode 100644 index 00000000..19e4cc79 --- /dev/null +++ b/composable/views/gesture/recognizer/enum.Response.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/gesture/enum.Response.html...

+ + + \ No newline at end of file diff --git a/composable/views/gesture/recognizer/fn.recognizer.html b/composable/views/gesture/recognizer/fn.recognizer.html new file mode 100644 index 00000000..cb553457 --- /dev/null +++ b/composable/views/gesture/recognizer/fn.recognizer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/gesture/fn.recognizer.html...

+ + + \ No newline at end of file diff --git a/composable/views/gesture/sidebar-items.js b/composable/views/gesture/sidebar-items.js new file mode 100644 index 00000000..b26e0e6f --- /dev/null +++ b/composable/views/gesture/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Response"],"fn":["recognizer"],"struct":["Id","Values"],"type":["State"]}; \ No newline at end of file diff --git a/composable/views/gesture/struct.Id.html b/composable/views/gesture/struct.Id.html new file mode 100644 index 00000000..d55c9ed4 --- /dev/null +++ b/composable/views/gesture/struct.Id.html @@ -0,0 +1,16 @@ +Id in composable::views::gesture - Rust

Struct composable::views::gesture::Id

source ·
pub struct Id(/* private fields */);
Available on crate features unreleased and views only.

Trait Implementations§

source§

impl Clone for Id

source§

fn clone(&self) -> Id

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl PartialEq for Id

source§

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

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Id

source§

impl Eq for Id

source§

impl StructuralPartialEq for Id

Auto Trait Implementations§

§

impl Freeze for Id

§

impl RefUnwindSafe for Id

§

impl Send for Id

§

impl Sync for Id

§

impl Unpin for Id

§

impl UnwindSafe for Id

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/gesture/struct.Values.html b/composable/views/gesture/struct.Values.html new file mode 100644 index 00000000..71ec968c --- /dev/null +++ b/composable/views/gesture/struct.Values.html @@ -0,0 +1,20 @@ +Values in composable::views::gesture - Rust

Struct composable::views::gesture::Values

source ·
#[non_exhaustive]
pub struct Values { + pub active: Option<Id>, + pub hover: Option<Id>, + pub focus: Option<Id>, +}
Available on crate features unreleased and views only.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§active: Option<Id>§hover: Option<Id>§focus: Option<Id>

Trait Implementations§

source§

impl Clone for Values

source§

fn clone(&self) -> Values

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Default for Values

source§

fn default() -> Values

Returns the “default value” for a type. Read more
source§

impl PartialEq for Values

source§

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

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Values

source§

impl DependencyDefault for Values

source§

impl Eq for Values

source§

impl StructuralPartialEq for Values

Auto Trait Implementations§

§

impl Freeze for Values

§

impl RefUnwindSafe for Values

§

impl Send for Values

§

impl Sync for Values

§

impl Unpin for Values

§

impl UnwindSafe for Values

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/gesture/type.State.html b/composable/views/gesture/type.State.html new file mode 100644 index 00000000..c15d2419 --- /dev/null +++ b/composable/views/gesture/type.State.html @@ -0,0 +1,12 @@ +State in composable::views::gesture - Rust

Type Alias composable::views::gesture::State

source ·
pub type State = Cell<Values>;
Available on crate features unreleased and views only.
Expand description

The user interface state carried between cycles by the application.

+ +
let state = State::default();
+
+let mut values = state.get();
+values.active = Some(id);
+
+// …
+
+state.set(values);
+
+

Aliased Type§

struct State { /* private fields */ }
\ No newline at end of file diff --git a/composable/views/gpu/index.html b/composable/views/gpu/index.html new file mode 100644 index 00000000..947e2219 --- /dev/null +++ b/composable/views/gpu/index.html @@ -0,0 +1,2 @@ +composable::views::gpu - Rust

Module composable::views::gpu

source ·
Available on crate features unreleased and views only.
Expand description

GPU Output for Views

+

Structs§

\ No newline at end of file diff --git a/composable/views/gpu/sidebar-items.js b/composable/views/gpu/sidebar-items.js new file mode 100644 index 00000000..2b63a8f5 --- /dev/null +++ b/composable/views/gpu/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Output"]}; \ No newline at end of file diff --git a/composable/views/gpu/struct.Output.html b/composable/views/gpu/struct.Output.html new file mode 100644 index 00000000..9bb7512f --- /dev/null +++ b/composable/views/gpu/struct.Output.html @@ -0,0 +1,53 @@ +Output in composable::views::gpu - Rust

Struct composable::views::gpu::Output

source ·
pub struct Output { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Implementations§

source§

impl Output

source

pub fn new(rounding: f32) -> Self

Creates an indexed-triangle data Output.

+
source

pub fn into_inner(self) -> (Vec<(i16, i16, [u8; 4])>, Vec<u32>)

Consumes the Output and returns the constructed indexed-triangle data.

+
    +
  • vertices are stored as (x, y, rgba) tuples
  • +
  • indices are stored as 32-bit offsets
  • +
+
§Example
+

A WGSL shader that consumes this Output’s output:

+
struct VertexInput {
+    @location(0) xy: u32,
+    @location(1) rgba: u32,
+};
+
+struct VertexOutput {
+    @builtin(position) xyzw: vec4<f32>,
+    @location(0) rgba: vec4<f32>,
+};
+
+@vertex
+fn vs_main(
+    in: VertexInput,
+) -> VertexOutput {
+    var out: VertexOutput;
+
+    out.xyzw = vec4<f32>(unpack2x16snorm(in.xy), 1.0, 1.0);
+    out.rgba = unpack4x8unorm(in.rgba);
+
+    return out;
+}
+
+@fragment
+fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
+    return in.rgba;
+}
+

Trait Implementations§

source§

impl Output for Output

source§

fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform)

Begins a new path. Read more
source§

fn line_to(&mut self, x: f32, y: f32)

Adds a line to the current path.
source§

fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32)

Adds a quadratic Bézier to the current path. Read more
source§

fn cubic_bezier_to( + &mut self, + x1: f32, + y1: f32, + x2: f32, + y2: f32, + x: f32, + y: f32, +)

Adds a cubic Bézier to the current path. Read more
source§

fn close(&mut self)

Closes the current path. Read more

Auto Trait Implementations§

§

impl Freeze for Output

§

impl RefUnwindSafe for Output

§

impl Send for Output

§

impl Sync for Output

§

impl Unpin for Output

§

impl UnwindSafe for Output

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/index.html b/composable/views/index.html new file mode 100644 index 00000000..0d278a6f --- /dev/null +++ b/composable/views/index.html @@ -0,0 +1,2 @@ +composable::views - Rust

Module composable::views

source ·
Available on crate features unreleased and views only.
Expand description

Optional view feature.

+

Re-exports§

  • pub use shapes::Shape;

Modules§

Structs§

Enums§

Traits§

  • A surface, or file format, that views may be rendered to.
  • User interface element and modifiers to re-configure it.

Type Aliases§

  • Alias for euclid::default::Box2D<f32>
  • Alias for euclid::default::SideOffsets2D<f32>
  • Alias for euclid::default::Point2D<f32>.
  • Alias for euclid::default::Size2D<f32>.
  • Alias for euclid::default::Transform2D<f32>
\ No newline at end of file diff --git a/composable/views/layout/spacing/struct.Spacer.html b/composable/views/layout/spacing/struct.Spacer.html new file mode 100644 index 00000000..a7e51e2c --- /dev/null +++ b/composable/views/layout/spacing/struct.Spacer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/struct.Spacer.html...

+ + + \ No newline at end of file diff --git a/composable/views/modifiers/fixed/struct.Fixed.html b/composable/views/modifiers/fixed/struct.Fixed.html new file mode 100644 index 00000000..1c502476 --- /dev/null +++ b/composable/views/modifiers/fixed/struct.Fixed.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/struct.Fixed.html...

+ + + \ No newline at end of file diff --git a/composable/views/modifiers/fixed/struct.FixedHeight.html b/composable/views/modifiers/fixed/struct.FixedHeight.html new file mode 100644 index 00000000..ee6e29d6 --- /dev/null +++ b/composable/views/modifiers/fixed/struct.FixedHeight.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/struct.FixedHeight.html...

+ + + \ No newline at end of file diff --git a/composable/views/modifiers/fixed/struct.FixedWidth.html b/composable/views/modifiers/fixed/struct.FixedWidth.html new file mode 100644 index 00000000..d2570441 --- /dev/null +++ b/composable/views/modifiers/fixed/struct.FixedWidth.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/struct.FixedWidth.html...

+ + + \ No newline at end of file diff --git a/composable/views/modifiers/padding/struct.Padding.html b/composable/views/modifiers/padding/struct.Padding.html new file mode 100644 index 00000000..d10c0733 --- /dev/null +++ b/composable/views/modifiers/padding/struct.Padding.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/struct.Padding.html...

+ + + \ No newline at end of file diff --git a/composable/views/output/gpu/index.html b/composable/views/output/gpu/index.html new file mode 100644 index 00000000..9c2133a4 --- /dev/null +++ b/composable/views/output/gpu/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/gpu/index.html...

+ + + \ No newline at end of file diff --git a/composable/views/output/gpu/struct.Output.html b/composable/views/output/gpu/struct.Output.html new file mode 100644 index 00000000..a97c81af --- /dev/null +++ b/composable/views/output/gpu/struct.Output.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/gpu/struct.Output.html...

+ + + \ No newline at end of file diff --git a/composable/views/output/svg/index.html b/composable/views/output/svg/index.html new file mode 100644 index 00000000..76b5c1f2 --- /dev/null +++ b/composable/views/output/svg/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/svg/index.html...

+ + + \ No newline at end of file diff --git a/composable/views/output/svg/struct.Output.html b/composable/views/output/svg/struct.Output.html new file mode 100644 index 00000000..94ae689d --- /dev/null +++ b/composable/views/output/svg/struct.Output.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/svg/struct.Output.html...

+ + + \ No newline at end of file diff --git a/composable/views/output/trait.Output.html b/composable/views/output/trait.Output.html new file mode 100644 index 00000000..5bc45c4d --- /dev/null +++ b/composable/views/output/trait.Output.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/trait.Output.html...

+ + + \ No newline at end of file diff --git a/composable/views/shapes/struct.Circle.html b/composable/views/shapes/struct.Circle.html new file mode 100644 index 00000000..65e05657 --- /dev/null +++ b/composable/views/shapes/struct.Circle.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/struct.Circle.html...

+ + + \ No newline at end of file diff --git a/composable/views/shapes/struct.ContinuousRoundedRectangle.html b/composable/views/shapes/struct.ContinuousRoundedRectangle.html new file mode 100644 index 00000000..1e4bc7cb --- /dev/null +++ b/composable/views/shapes/struct.ContinuousRoundedRectangle.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/struct.ContinuousRoundedRectangle.html...

+ + + \ No newline at end of file diff --git a/composable/views/shapes/struct.Ellipse.html b/composable/views/shapes/struct.Ellipse.html new file mode 100644 index 00000000..7bafdfb9 --- /dev/null +++ b/composable/views/shapes/struct.Ellipse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/struct.Ellipse.html...

+ + + \ No newline at end of file diff --git a/composable/views/shapes/struct.Rectangle.html b/composable/views/shapes/struct.Rectangle.html new file mode 100644 index 00000000..adbc2060 --- /dev/null +++ b/composable/views/shapes/struct.Rectangle.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/struct.Rectangle.html...

+ + + \ No newline at end of file diff --git a/composable/views/shapes/struct.RoundedRectangle.html b/composable/views/shapes/struct.RoundedRectangle.html new file mode 100644 index 00000000..f33b3fb7 --- /dev/null +++ b/composable/views/shapes/struct.RoundedRectangle.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/struct.RoundedRectangle.html...

+ + + \ No newline at end of file diff --git a/composable/views/shapes/trait.Path.html b/composable/views/shapes/trait.Path.html new file mode 100644 index 00000000..0df0a821 --- /dev/null +++ b/composable/views/shapes/trait.Path.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../composable/views/trait.Path.html...

+ + + \ No newline at end of file diff --git a/composable/views/sidebar-items.js b/composable/views/sidebar-items.js new file mode 100644 index 00000000..9ff04773 --- /dev/null +++ b/composable/views/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Event","Gesture"],"mod":["gesture","gpu","svg","text","ui"],"struct":["Circle","ContinuousRoundedRectangle","Ellipse","Fixed","FixedHeight","FixedWidth","Padding","Rectangle","RoundedRectangle","Spacer","Text"],"trait":["Output","Path","View"],"type":["Bounds","Offsets","Point","Size","Transform"]}; \ No newline at end of file diff --git a/composable/views/struct.Circle.html b/composable/views/struct.Circle.html new file mode 100644 index 00000000..326850eb --- /dev/null +++ b/composable/views/struct.Circle.html @@ -0,0 +1,21 @@ +Circle in composable::views - Rust

Struct composable::views::Circle

source ·
pub struct Circle {
+    pub rgba: [u8; 4],
+}
Available on crate features unreleased and views only.

Fields§

§rgba: [u8; 4]

Trait Implementations§

source§

impl Path for Circle

source§

fn draw( + &self, + x: f32, + y: f32, + w: f32, + h: f32, + transform: &Transform, + onto: &mut impl Output, +)

source§

fn fill(self) -> Shape<Self>

source§

fn fixed(self, width: f32, height: f32) -> Shape<Self>

Auto Trait Implementations§

§

impl Freeze for Circle

§

impl RefUnwindSafe for Circle

§

impl Send for Circle

§

impl Sync for Circle

§

impl Unpin for Circle

§

impl UnwindSafe for Circle

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.ContinuousRoundedRectangle.html b/composable/views/struct.ContinuousRoundedRectangle.html new file mode 100644 index 00000000..47f6df49 --- /dev/null +++ b/composable/views/struct.ContinuousRoundedRectangle.html @@ -0,0 +1,19 @@ +ContinuousRoundedRectangle in composable::views - Rust

Struct composable::views::ContinuousRoundedRectangle

source ·
pub struct ContinuousRoundedRectangle { /* private fields */ }
Available on crate features unreleased and views only.

Trait Implementations§

source§

impl Path for ContinuousRoundedRectangle

source§

fn draw( + &self, + x: f32, + y: f32, + w: f32, + h: f32, + transform: &Transform, + onto: &mut impl Output, +)

source§

fn fill(self) -> Shape<Self>

source§

fn fixed(self, width: f32, height: f32) -> Shape<Self>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.Ellipse.html b/composable/views/struct.Ellipse.html new file mode 100644 index 00000000..0f8b4e2a --- /dev/null +++ b/composable/views/struct.Ellipse.html @@ -0,0 +1,21 @@ +Ellipse in composable::views - Rust

Struct composable::views::Ellipse

source ·
pub struct Ellipse {
+    pub rgba: [u8; 4],
+}
Available on crate features unreleased and views only.

Fields§

§rgba: [u8; 4]

Trait Implementations§

source§

impl Path for Ellipse

source§

fn draw( + &self, + x: f32, + y: f32, + w: f32, + h: f32, + transform: &Transform, + onto: &mut impl Output, +)

source§

fn fill(self) -> Shape<Self>

source§

fn fixed(self, width: f32, height: f32) -> Shape<Self>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.Fixed.html b/composable/views/struct.Fixed.html new file mode 100644 index 00000000..9fff14d4 --- /dev/null +++ b/composable/views/struct.Fixed.html @@ -0,0 +1,17 @@ +Fixed in composable::views - Rust

Struct composable::views::Fixed

source ·
pub struct Fixed<V> { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Trait Implementations§

source§

impl<V: View> View for Fixed<V>

source§

fn size(&self) -> Size

The intrinsic size of the View
source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

User-interface Event handling of the View
source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

How the View is drawn
source§

fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self>

Add padding to all sides of the View
source§

fn padding_top(self, pad: f32) -> Padding<Self>

Add padding to the top of the View
source§

fn padding_right(self, pad: f32) -> Padding<Self>

Add padding to the right side of the View
source§

fn padding_bottom(self, pad: f32) -> Padding<Self>

Add padding to the bottom of the View
source§

fn padding_left(self, pad: f32) -> Padding<Self>

Add padding to the left side of the View
source§

fn padding_horizontal(self, pad: f32) -> Padding<Self>

Add padding to the horizontal sides of the View
source§

fn padding_vertical(self, pad: f32) -> Padding<Self>

Add padding to the vertical sides of the View
source§

fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self>

Add different padding to the horizontal and vertical sides of the View
source§

fn padding_all(self, pad: f32) -> Padding<Self>

Add the same padding to all sides of the View
source§

fn fixed(self, width: f32, height: f32) -> impl View

Set the size of the View to a fixed value.
source§

fn width(self, width: f32) -> impl View

source§

fn height(self, height: f32) -> impl View

source§

fn across(self) -> impl View

Causes a tuple of Views to cascade horizontally, rather than vertically. Read more

Auto Trait Implementations§

§

impl<V> Freeze for Fixed<V>
where + V: Freeze,

§

impl<V> RefUnwindSafe for Fixed<V>
where + V: RefUnwindSafe,

§

impl<V> Send for Fixed<V>
where + V: Send,

§

impl<V> Sync for Fixed<V>
where + V: Sync,

§

impl<V> Unpin for Fixed<V>
where + V: Unpin,

§

impl<V> UnwindSafe for Fixed<V>
where + V: UnwindSafe,

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.FixedHeight.html b/composable/views/struct.FixedHeight.html new file mode 100644 index 00000000..cb3b2925 --- /dev/null +++ b/composable/views/struct.FixedHeight.html @@ -0,0 +1,17 @@ +FixedHeight in composable::views - Rust

Struct composable::views::FixedHeight

source ·
pub struct FixedHeight<V: View> { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Trait Implementations§

source§

impl<V: View> View for FixedHeight<V>

source§

fn size(&self) -> Size

The intrinsic size of the View
source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

User-interface Event handling of the View
source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

How the View is drawn
source§

fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self>

Add padding to all sides of the View
source§

fn padding_top(self, pad: f32) -> Padding<Self>

Add padding to the top of the View
source§

fn padding_right(self, pad: f32) -> Padding<Self>

Add padding to the right side of the View
source§

fn padding_bottom(self, pad: f32) -> Padding<Self>

Add padding to the bottom of the View
source§

fn padding_left(self, pad: f32) -> Padding<Self>

Add padding to the left side of the View
source§

fn padding_horizontal(self, pad: f32) -> Padding<Self>

Add padding to the horizontal sides of the View
source§

fn padding_vertical(self, pad: f32) -> Padding<Self>

Add padding to the vertical sides of the View
source§

fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self>

Add different padding to the horizontal and vertical sides of the View
source§

fn padding_all(self, pad: f32) -> Padding<Self>

Add the same padding to all sides of the View
source§

fn fixed(self, width: f32, height: f32) -> impl View

Set the size of the View to a fixed value.
source§

fn width(self, width: f32) -> impl View

source§

fn height(self, height: f32) -> impl View

source§

fn across(self) -> impl View

Causes a tuple of Views to cascade horizontally, rather than vertically. Read more

Auto Trait Implementations§

§

impl<V> Freeze for FixedHeight<V>
where + V: Freeze,

§

impl<V> RefUnwindSafe for FixedHeight<V>
where + V: RefUnwindSafe,

§

impl<V> Send for FixedHeight<V>
where + V: Send,

§

impl<V> Sync for FixedHeight<V>
where + V: Sync,

§

impl<V> Unpin for FixedHeight<V>
where + V: Unpin,

§

impl<V> UnwindSafe for FixedHeight<V>
where + V: UnwindSafe,

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.FixedWidth.html b/composable/views/struct.FixedWidth.html new file mode 100644 index 00000000..4afb2710 --- /dev/null +++ b/composable/views/struct.FixedWidth.html @@ -0,0 +1,17 @@ +FixedWidth in composable::views - Rust

Struct composable::views::FixedWidth

source ·
pub struct FixedWidth<V: View> { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Trait Implementations§

source§

impl<V: View> View for FixedWidth<V>

source§

fn size(&self) -> Size

The intrinsic size of the View
source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

User-interface Event handling of the View
source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

How the View is drawn
source§

fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self>

Add padding to all sides of the View
source§

fn padding_top(self, pad: f32) -> Padding<Self>

Add padding to the top of the View
source§

fn padding_right(self, pad: f32) -> Padding<Self>

Add padding to the right side of the View
source§

fn padding_bottom(self, pad: f32) -> Padding<Self>

Add padding to the bottom of the View
source§

fn padding_left(self, pad: f32) -> Padding<Self>

Add padding to the left side of the View
source§

fn padding_horizontal(self, pad: f32) -> Padding<Self>

Add padding to the horizontal sides of the View
source§

fn padding_vertical(self, pad: f32) -> Padding<Self>

Add padding to the vertical sides of the View
source§

fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self>

Add different padding to the horizontal and vertical sides of the View
source§

fn padding_all(self, pad: f32) -> Padding<Self>

Add the same padding to all sides of the View
source§

fn fixed(self, width: f32, height: f32) -> impl View

Set the size of the View to a fixed value.
source§

fn width(self, width: f32) -> impl View

source§

fn height(self, height: f32) -> impl View

source§

fn across(self) -> impl View

Causes a tuple of Views to cascade horizontally, rather than vertically. Read more

Auto Trait Implementations§

§

impl<V> Freeze for FixedWidth<V>
where + V: Freeze,

§

impl<V> RefUnwindSafe for FixedWidth<V>
where + V: RefUnwindSafe,

§

impl<V> Send for FixedWidth<V>
where + V: Send,

§

impl<V> Sync for FixedWidth<V>
where + V: Sync,

§

impl<V> Unpin for FixedWidth<V>
where + V: Unpin,

§

impl<V> UnwindSafe for FixedWidth<V>
where + V: UnwindSafe,

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.Padding.html b/composable/views/struct.Padding.html new file mode 100644 index 00000000..fe737b89 --- /dev/null +++ b/composable/views/struct.Padding.html @@ -0,0 +1,17 @@ +Padding in composable::views - Rust

Struct composable::views::Padding

source ·
pub struct Padding<V> { /* private fields */ }
Available on crate features unreleased and views only.

Trait Implementations§

source§

impl<V: View> View for Padding<V>

source§

fn size(&self) -> Size

The intrinsic size of the View
source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

User-interface Event handling of the View
source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

How the View is drawn
source§

fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self>

Add padding to all sides of the View
source§

fn padding_top(self, pad: f32) -> Padding<Self>

Add padding to the top of the View
source§

fn padding_right(self, pad: f32) -> Padding<Self>

Add padding to the right side of the View
source§

fn padding_bottom(self, pad: f32) -> Padding<Self>

Add padding to the bottom of the View
source§

fn padding_left(self, pad: f32) -> Padding<Self>

Add padding to the left side of the View
source§

fn padding_horizontal(self, pad: f32) -> Padding<Self>

Add padding to the horizontal sides of the View
source§

fn padding_vertical(self, pad: f32) -> Padding<Self>

Add padding to the vertical sides of the View
source§

fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self>

Add different padding to the horizontal and vertical sides of the View
source§

fn padding_all(self, pad: f32) -> Padding<Self>

Add the same padding to all sides of the View
source§

fn fixed(self, width: f32, height: f32) -> impl View

Set the size of the View to a fixed value.
source§

fn width(self, width: f32) -> impl View

source§

fn height(self, height: f32) -> impl View

source§

fn across(self) -> impl View

Causes a tuple of Views to cascade horizontally, rather than vertically. Read more

Auto Trait Implementations§

§

impl<V> Freeze for Padding<V>
where + V: Freeze,

§

impl<V> RefUnwindSafe for Padding<V>
where + V: RefUnwindSafe,

§

impl<V> Send for Padding<V>
where + V: Send,

§

impl<V> Sync for Padding<V>
where + V: Sync,

§

impl<V> Unpin for Padding<V>
where + V: Unpin,

§

impl<V> UnwindSafe for Padding<V>
where + V: UnwindSafe,

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.Rectangle.html b/composable/views/struct.Rectangle.html new file mode 100644 index 00000000..fd489bb8 --- /dev/null +++ b/composable/views/struct.Rectangle.html @@ -0,0 +1,21 @@ +Rectangle in composable::views - Rust

Struct composable::views::Rectangle

source ·
pub struct Rectangle {
+    pub rgba: [u8; 4],
+}
Available on crate features unreleased and views only.

Fields§

§rgba: [u8; 4]

Implementations§

Trait Implementations§

source§

impl Path for Rectangle

source§

fn draw( + &self, + x: f32, + y: f32, + w: f32, + h: f32, + transform: &Transform, + onto: &mut impl Output, +)

source§

fn fill(self) -> Shape<Self>

source§

fn fixed(self, width: f32, height: f32) -> Shape<Self>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.RoundedRectangle.html b/composable/views/struct.RoundedRectangle.html new file mode 100644 index 00000000..5c6a32a7 --- /dev/null +++ b/composable/views/struct.RoundedRectangle.html @@ -0,0 +1,19 @@ +RoundedRectangle in composable::views - Rust

Struct composable::views::RoundedRectangle

source ·
pub struct RoundedRectangle { /* private fields */ }
Available on crate features unreleased and views only.

Implementations§

Trait Implementations§

source§

impl Path for RoundedRectangle

source§

fn draw( + &self, + x: f32, + y: f32, + w: f32, + h: f32, + transform: &Transform, + onto: &mut impl Output, +)

source§

fn fill(self) -> Shape<Self>

source§

fn fixed(self, width: f32, height: f32) -> Shape<Self>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.Spacer.html b/composable/views/struct.Spacer.html new file mode 100644 index 00000000..26e81e83 --- /dev/null +++ b/composable/views/struct.Spacer.html @@ -0,0 +1,11 @@ +Spacer in composable::views - Rust

Struct composable::views::Spacer

source ·
pub struct Spacer(/* private fields */);
Available on crate features unreleased and views only.

Implementations§

source§

impl Spacer

source

pub fn fill() -> Self

source

pub fn fixed(width: f32, height: f32) -> Self

source

pub fn width(width: f32) -> Self

source

pub fn height(height: f32) -> Self

source

pub fn empty() -> Self

Trait Implementations§

source§

impl View for Spacer

source§

fn size(&self) -> Size

The intrinsic size of the View
source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

How the View is drawn
source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

User-interface Event handling of the View
source§

fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self>

Add padding to all sides of the View
source§

fn padding_top(self, pad: f32) -> Padding<Self>

Add padding to the top of the View
source§

fn padding_right(self, pad: f32) -> Padding<Self>

Add padding to the right side of the View
source§

fn padding_bottom(self, pad: f32) -> Padding<Self>

Add padding to the bottom of the View
source§

fn padding_left(self, pad: f32) -> Padding<Self>

Add padding to the left side of the View
source§

fn padding_horizontal(self, pad: f32) -> Padding<Self>

Add padding to the horizontal sides of the View
source§

fn padding_vertical(self, pad: f32) -> Padding<Self>

Add padding to the vertical sides of the View
source§

fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self>

Add different padding to the horizontal and vertical sides of the View
source§

fn padding_all(self, pad: f32) -> Padding<Self>

Add the same padding to all sides of the View
source§

fn fixed(self, width: f32, height: f32) -> impl View

Set the size of the View to a fixed value.
source§

fn width(self, width: f32) -> impl View

source§

fn height(self, height: f32) -> impl View

source§

fn across(self) -> impl View

Causes a tuple of Views to cascade horizontally, rather than vertically. Read more

Auto Trait Implementations§

§

impl !Freeze for Spacer

§

impl !RefUnwindSafe for Spacer

§

impl Send for Spacer

§

impl !Sync for Spacer

§

impl Unpin for Spacer

§

impl UnwindSafe for Spacer

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/struct.Text.html b/composable/views/struct.Text.html new file mode 100644 index 00000000..d3afc733 --- /dev/null +++ b/composable/views/struct.Text.html @@ -0,0 +1,8 @@ +Text in composable::views - Rust

Struct composable::views::Text

source ·
pub struct Text<'a> { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Text data

+

Implementations§

source§

impl Text<'_>

source

pub fn height(&self) -> f32

Height of the Text’s font.

+
source

pub fn ascender(&self) -> f32

Ascender height of the Text’s font.

+
source

pub fn descender(&self) -> f32

Descender height of the Text’s font.
+Note that this is a negative value.

+
source

pub fn capital_height(&self) -> f32

Capital height of the Text’s font.

+
source

pub fn line_gap(&self) -> f32

Line gap of the Text’s font.

+
\ No newline at end of file diff --git a/composable/views/svg/index.html b/composable/views/svg/index.html new file mode 100644 index 00000000..a5b4747a --- /dev/null +++ b/composable/views/svg/index.html @@ -0,0 +1,2 @@ +composable::views::svg - Rust

Module composable::views::svg

source ·
Available on crate features unreleased and views only.
Expand description

SVG Output for Views

+

Structs§

\ No newline at end of file diff --git a/composable/views/svg/sidebar-items.js b/composable/views/svg/sidebar-items.js new file mode 100644 index 00000000..2b63a8f5 --- /dev/null +++ b/composable/views/svg/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Output"]}; \ No newline at end of file diff --git a/composable/views/svg/struct.Output.html b/composable/views/svg/struct.Output.html new file mode 100644 index 00000000..ae0866c6 --- /dev/null +++ b/composable/views/svg/struct.Output.html @@ -0,0 +1,21 @@ +Output in composable::views::svg - Rust

Struct composable::views::svg::Output

source ·
pub struct Output { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Implementations§

source§

impl Output

source

pub fn new(width: f32, height: f32) -> Self

Creates a Scalable Vector Graphics Output.

+
source

pub fn into_inner(self) -> String

Consumes the Output and returns the constructed SVG string.

+

Trait Implementations§

source§

impl Output for Output

source§

fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform)

Begins a new path. Read more
source§

fn line_to(&mut self, x: f32, y: f32)

Adds a line to the current path.
source§

fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32)

Adds a quadratic Bézier to the current path. Read more
source§

fn cubic_bezier_to( + &mut self, + x1: f32, + y1: f32, + x2: f32, + y2: f32, + x: f32, + y: f32, +)

Adds a cubic Bézier to the current path. Read more
source§

fn close(&mut self)

Closes the current path. Read more

Auto Trait Implementations§

§

impl Freeze for Output

§

impl !RefUnwindSafe for Output

§

impl Send for Output

§

impl Sync for Output

§

impl Unpin for Output

§

impl !UnwindSafe for Output

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/text/enum.Direction.html b/composable/views/text/enum.Direction.html new file mode 100644 index 00000000..e52399d1 --- /dev/null +++ b/composable/views/text/enum.Direction.html @@ -0,0 +1,31 @@ +Direction in composable::views::text - Rust

Enum composable::views::text::Direction

pub enum Direction {
+    Invalid,
+    LeftToRight,
+    RightToLeft,
+    TopToBottom,
+    BottomToTop,
+}
Available on crate features unreleased and views only.
Expand description

Defines the direction in which text is to be read.

+

Variants§

§

Invalid

Initial, unset direction.

+
§

LeftToRight

Text is set horizontally from left to right.

+
§

RightToLeft

Text is set horizontally from right to left.

+
§

TopToBottom

Text is set vertically from top to bottom.

+
§

BottomToTop

Text is set vertically from bottom to top.

+

Trait Implementations§

§

impl Clone for Direction

§

fn clone(&self) -> Direction

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
§

impl Debug for Direction

§

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

Formats the value using the given formatter. Read more
§

impl Default for Direction

§

fn default() -> Direction

Returns the “default value” for a type. Read more
§

impl FromStr for Direction

§

type Err = &'static str

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<Direction, <Direction as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl Hash for Direction

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

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
§

impl PartialEq for Direction

§

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

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Direction

§

impl Eq for Direction

§

impl StructuralPartialEq for Direction

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/text/font/enum.Direction.html b/composable/views/text/font/enum.Direction.html new file mode 100644 index 00000000..6799f670 --- /dev/null +++ b/composable/views/text/font/enum.Direction.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/text/enum.Direction.html...

+ + + \ No newline at end of file diff --git a/composable/views/text/font/struct.Font.html b/composable/views/text/font/struct.Font.html new file mode 100644 index 00000000..ef575f47 --- /dev/null +++ b/composable/views/text/font/struct.Font.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/text/struct.Font.html...

+ + + \ No newline at end of file diff --git a/composable/views/text/font/struct.FontConfig.html b/composable/views/text/font/struct.FontConfig.html new file mode 100644 index 00000000..d8e0564e --- /dev/null +++ b/composable/views/text/font/struct.FontConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/text/struct.FontConfig.html...

+ + + \ No newline at end of file diff --git a/composable/views/text/font/struct.Glyphs.html b/composable/views/text/font/struct.Glyphs.html new file mode 100644 index 00000000..9045dbc2 --- /dev/null +++ b/composable/views/text/font/struct.Glyphs.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/text/struct.Glyphs.html...

+ + + \ No newline at end of file diff --git a/composable/views/text/font/struct.Language.html b/composable/views/text/font/struct.Language.html new file mode 100644 index 00000000..50758f1c --- /dev/null +++ b/composable/views/text/font/struct.Language.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/text/struct.Language.html...

+ + + \ No newline at end of file diff --git a/composable/views/text/font/struct.Script.html b/composable/views/text/font/struct.Script.html new file mode 100644 index 00000000..d7db7a6d --- /dev/null +++ b/composable/views/text/font/struct.Script.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../composable/views/text/struct.Script.html...

+ + + \ No newline at end of file diff --git a/composable/views/text/index.html b/composable/views/text/index.html new file mode 100644 index 00000000..b3e2798a --- /dev/null +++ b/composable/views/text/index.html @@ -0,0 +1,2 @@ +composable::views::text - Rust

Module composable::views::text

source ·
Available on crate features unreleased and views only.
Expand description

Text handling for View construction.

+

Structs§

Enums§

  • Defines the direction in which text is to be read.
\ No newline at end of file diff --git a/composable/views/text/sidebar-items.js b/composable/views/text/sidebar-items.js new file mode 100644 index 00000000..0c2309c1 --- /dev/null +++ b/composable/views/text/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Direction"],"struct":["Font","FontConfig","Glyphs","Language","Script"]}; \ No newline at end of file diff --git a/composable/views/text/struct.Font.html b/composable/views/text/struct.Font.html new file mode 100644 index 00000000..2266db14 --- /dev/null +++ b/composable/views/text/struct.Font.html @@ -0,0 +1,27 @@ +Font in composable::views::text - Rust

Struct composable::views::text::Font

source ·
pub struct Font<'a> { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Implementations§

source§

impl<'a> Font<'a>

source

pub fn full_name(&self) -> Option<String>

Full font name that reflects all family and relevant subfamily descriptors.

+
source

pub fn family(&self) -> Option<String>

Family name.

+
source

pub fn style(&self) -> Option<String>

Subfamily name.

+
source

pub fn identifier(&self) -> Option<String>

Unique font identifier

+
source

pub fn version(&self) -> Option<String>

Should begin with the syntax “Version N.M” +(upper case, lower case, or mixed, with a space between “Version” and the number).

+
source

pub fn size(&self) -> f32

Font size in points.

+
source

pub fn ascender(&self) -> f32

Horizontal face ascender.

+
source

pub fn descender(&self) -> f32

Horizontal face descender,

+
source

pub fn height(&self) -> f32

Horizontal height,

+
source

pub fn capital_height(&self) -> f32

Capital height,

+
source

pub fn line_gap(&self) -> f32

Line gap,

+
source

pub fn text(&self, rgba: [u8; 4], string: &str) -> Text<'_>

Returns a Text in this font.

+
source§

impl<'a> Font<'a>

source

pub fn from(data: &'a [u8]) -> Option<FontConfig<'_>>

Create a Font from the raw font data.

+
source

pub fn from_collection(data: &'a [u8], index: u32) -> Option<FontConfig<'_>>

Create a Font from a font collection. +Returns the font at index, if any

+

Auto Trait Implementations§

§

impl<'a> Freeze for Font<'a>

§

impl<'a> !RefUnwindSafe for Font<'a>

§

impl<'a> Send for Font<'a>

§

impl<'a> Sync for Font<'a>

§

impl<'a> Unpin for Font<'a>

§

impl<'a> !UnwindSafe for Font<'a>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/text/struct.FontConfig.html b/composable/views/text/struct.FontConfig.html new file mode 100644 index 00000000..b3146479 --- /dev/null +++ b/composable/views/text/struct.FontConfig.html @@ -0,0 +1,14 @@ +FontConfig in composable::views::text - Rust

Struct composable::views::text::FontConfig

source ·
pub struct FontConfig<'a> { /* private fields */ }
Available on crate features unreleased and views only.
Expand description

Implementations§

source§

impl<'a> FontConfig<'a>

source

pub fn direction(self, direction: Direction) -> Self

source

pub fn script(self, script: Script) -> Self

source

pub fn language(self, language: Language) -> Self

source

pub fn feature(self, tag: &[u8; 4], value: u32) -> Self

source

pub fn weight(self, weight: f32) -> Self

source

pub fn size(self, size: f32) -> Font<'a>

The final step in building a Font.

+

Trait Implementations§

source§

impl<'a> Clone for FontConfig<'a>

source§

fn clone(&self) -> FontConfig<'a>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for FontConfig<'a>

§

impl<'a> RefUnwindSafe for FontConfig<'a>

§

impl<'a> Send for FontConfig<'a>

§

impl<'a> Sync for FontConfig<'a>

§

impl<'a> Unpin for FontConfig<'a>

§

impl<'a> UnwindSafe for FontConfig<'a>

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/text/struct.Glyphs.html b/composable/views/text/struct.Glyphs.html new file mode 100644 index 00000000..4cd65ab5 --- /dev/null +++ b/composable/views/text/struct.Glyphs.html @@ -0,0 +1,22 @@ +Glyphs in composable::views::text - Rust

Struct composable::views::text::Glyphs

pub struct Glyphs(/* private fields */);
Available on crate features unreleased and views only.
Expand description

A buffer that contains the results of the shaping process.

+

Implementations§

§

impl GlyphBuffer

pub fn len(&self) -> usize

Returns the length of the data of the buffer.

+

When called before shaping this is the number of unicode codepoints +contained in the buffer. When called after shaping it returns the number +of glyphs stored.

+

pub fn is_empty(&self) -> bool

Returns true if the buffer contains no elements.

+

pub fn glyph_infos(&self) -> &[hb_glyph_info_t]

Get the glyph infos.

+

pub fn glyph_positions(&self) -> &[GlyphPosition]

Get the glyph positions.

+

pub fn clear(self) -> UnicodeBuffer

Clears the content of the glyph buffer and returns an empty +UnicodeBuffer reusing the existing allocation.

+

pub fn serialize(&self, face: &hb_font_t<'_>, flags: SerializeFlags) -> String

Converts the glyph buffer content into a string.

+

Trait Implementations§

§

impl Debug for GlyphBuffer

§

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

Formats the value using the given formatter. 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> 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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/text/struct.Language.html b/composable/views/text/struct.Language.html new file mode 100644 index 00000000..83e5db24 --- /dev/null +++ b/composable/views/text/struct.Language.html @@ -0,0 +1,20 @@ +Language in composable::views::text - Rust

Struct composable::views::text::Language

pub struct Language(/* private fields */);
Available on crate features unreleased and views only.
Expand description

A script language.

+

Implementations§

§

impl Language

pub fn as_str(&self) -> &str

Returns the language as a string.

+

Trait Implementations§

§

impl Clone for Language

§

fn clone(&self) -> Language

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
§

impl Debug for Language

§

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

Formats the value using the given formatter. Read more
§

impl FromStr for Language

§

type Err = &'static str

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<Language, <Language as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl Hash for Language

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

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
§

impl PartialEq for Language

§

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

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for Language

§

impl StructuralPartialEq for Language

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/text/struct.Script.html b/composable/views/text/struct.Script.html new file mode 100644 index 00000000..81379647 --- /dev/null +++ b/composable/views/text/struct.Script.html @@ -0,0 +1,27 @@ +Script in composable::views::text - Rust

Struct composable::views::text::Script

pub struct Script(/* private fields */);
Available on crate features unreleased and views only.
Expand description

A text script.

+

Implementations§

§

impl Script

pub fn from_iso15924_tag(tag: Tag) -> Option<Script>

Converts an ISO 15924 script tag to a corresponding Script.

+

pub fn tag(&self) -> Tag

Returns script’s tag.

+

Trait Implementations§

§

impl Clone for Script

§

fn clone(&self) -> Script

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
§

impl Debug for Script

§

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

Formats the value using the given formatter. Read more
§

impl FromStr for Script

§

type Err = &'static str

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<Script, <Script as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl Hash for Script

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

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
§

impl Ord for Script

§

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

This method returns an Ordering between self and other. Read more
1.21.0 · source§

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

Compares and returns the maximum of two values. Read more
1.21.0 · source§

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

Compares and returns the minimum of two values. Read more
1.50.0 · source§

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

Restrict a value to a certain interval. Read more
§

impl PartialEq for Script

§

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

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for Script

§

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

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

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

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

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

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

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

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

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

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl Copy for Script

§

impl Eq for Script

§

impl StructuralPartialEq for Script

Auto Trait Implementations§

§

impl Freeze for Script

§

impl RefUnwindSafe for Script

§

impl Send for Script

§

impl Sync for Script

§

impl Unpin for Script

§

impl UnwindSafe for Script

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/trait.Output.html b/composable/views/trait.Output.html new file mode 100644 index 00000000..f7eb760e --- /dev/null +++ b/composable/views/trait.Output.html @@ -0,0 +1,35 @@ +Output in composable::views - Rust

Trait composable::views::Output

source ·
pub trait Output: Sized {
+    // Required methods
+    fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform);
+    fn line_to(&mut self, x: f32, y: f32);
+    fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32);
+    fn cubic_bezier_to(
+        &mut self,
+        x1: f32,
+        y1: f32,
+        x2: f32,
+        y2: f32,
+        x: f32,
+        y: f32,
+    );
+    fn close(&mut self);
+}
Available on crate features unreleased and views only.
Expand description

A surface, or file format, that views may be rendered to.

+

Required Methods§

source

fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform)

Begins a new path.

+

The path should be continued with a series of line_to, quadratic_bezier_to, and/or +cubic_bezier_to calls and ended with a call to close.

+
source

fn line_to(&mut self, x: f32, y: f32)

Adds a line to the current path.

+
source

fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32)

Adds a quadratic Bézier to the current path.

+

(x1, y1) represents the Bézier control point.

+
source

fn cubic_bezier_to( + &mut self, + x1: f32, + y1: f32, + x2: f32, + y2: f32, + x: f32, + y: f32, +)

Adds a cubic Bézier to the current path.

+

(x1, y1) and (x2, y2) represent the Bézier control points.

+
source

fn close(&mut self)

Closes the current path.

+

Once this method has been called there is no current path until begin is called again.

+

Object Safety§

This trait is not object safe.

Implementors§

source§

impl Output for composable::views::gpu::Output

source§

impl Output for composable::views::svg::Output

\ No newline at end of file diff --git a/composable/views/trait.Path.html b/composable/views/trait.Path.html new file mode 100644 index 00000000..e5db5414 --- /dev/null +++ b/composable/views/trait.Path.html @@ -0,0 +1,24 @@ +Path in composable::views - Rust

Trait composable::views::Path

source ·
pub trait Path: Sized {
+    // Required method
+    fn draw(
+        &self,
+        x: f32,
+        y: f32,
+        w: f32,
+        h: f32,
+        transform: &Transform,
+        onto: &mut impl Output,
+    );
+
+    // Provided methods
+    fn fill(self) -> Shape<Self> { ... }
+    fn fixed(self, width: f32, height: f32) -> Shape<Self> { ... }
+}
Available on crate features unreleased and views only.

Required Methods§

source

fn draw( + &self, + x: f32, + y: f32, + w: f32, + h: f32, + transform: &Transform, + onto: &mut impl Output, +)

Provided Methods§

source

fn fill(self) -> Shape<Self>

source

fn fixed(self, width: f32, height: f32) -> Shape<Self>

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/composable/views/trait.View.html b/composable/views/trait.View.html new file mode 100644 index 00000000..4afa734d --- /dev/null +++ b/composable/views/trait.View.html @@ -0,0 +1,44 @@ +View in composable::views - Rust

Trait composable::views::View

source ·
pub trait View: Sized {
+
Show 16 methods // Required methods + fn size(&self) -> Size; + fn draw(&self, bounds: Bounds, onto: &mut impl Output); + + // Provided methods + fn event(&self, event: Event, offset: Point, bounds: Bounds) { ... } + fn padding( + self, + top: f32, + right: f32, + bottom: f32, + left: f32, + ) -> Padding<Self> { ... } + fn padding_top(self, pad: f32) -> Padding<Self> { ... } + fn padding_right(self, pad: f32) -> Padding<Self> { ... } + fn padding_bottom(self, pad: f32) -> Padding<Self> { ... } + fn padding_left(self, pad: f32) -> Padding<Self> { ... } + fn padding_horizontal(self, pad: f32) -> Padding<Self> { ... } + fn padding_vertical(self, pad: f32) -> Padding<Self> { ... } + fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self> { ... } + fn padding_all(self, pad: f32) -> Padding<Self> { ... } + fn fixed(self, width: f32, height: f32) -> impl View { ... } + fn width(self, width: f32) -> impl View { ... } + fn height(self, height: f32) -> impl View { ... } + fn across(self) -> impl View { ... } +
}
Available on crate features unreleased and views only.
Expand description

User interface element and modifiers to re-configure it.

+

Required Methods§

source

fn size(&self) -> Size

The intrinsic size of the View

+
source

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

How the View is drawn

+

Provided Methods§

source

fn event(&self, event: Event, offset: Point, bounds: Bounds)

User-interface Event handling of the View

+
source

fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self>

Add padding to all sides of the View

+
source

fn padding_top(self, pad: f32) -> Padding<Self>

Add padding to the top of the View

+
source

fn padding_right(self, pad: f32) -> Padding<Self>

Add padding to the right side of the View

+
source

fn padding_bottom(self, pad: f32) -> Padding<Self>

Add padding to the bottom of the View

+
source

fn padding_left(self, pad: f32) -> Padding<Self>

Add padding to the left side of the View

+
source

fn padding_horizontal(self, pad: f32) -> Padding<Self>

Add padding to the horizontal sides of the View

+
source

fn padding_vertical(self, pad: f32) -> Padding<Self>

Add padding to the vertical sides of the View

+
source

fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self>

Add different padding to the horizontal and vertical sides of the View

+
source

fn padding_all(self, pad: f32) -> Padding<Self>

Add the same padding to all sides of the View

+
source

fn fixed(self, width: f32, height: f32) -> impl View

Set the size of the View to a fixed value.

+
source

fn width(self, width: f32) -> impl View

source

fn height(self, height: f32) -> impl View

source

fn across(self) -> impl View

Causes a tuple of Views to cascade horizontally, rather than vertically.

+
§Note
+

For other views, nothing changes

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T: View> View for Option<T>

source§

fn size(&self) -> Size

source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

source§

impl<T: View> View for Box<T>

source§

fn size(&self) -> Size

source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

source§

impl<T: View, E: View> View for Result<T, E>

source§

fn size(&self) -> Size

source§

fn event(&self, event: Event, offset: Point, bounds: Bounds)

source§

fn draw(&self, bounds: Bounds, onto: &mut impl Output)

Implementors§

source§

impl View for Spacer

source§

impl<V: View> View for Fixed<V>

source§

impl<V: View> View for FixedHeight<V>

source§

impl<V: View> View for FixedWidth<V>

source§

impl<V: View> View for Padding<V>

\ No newline at end of file diff --git a/composable/views/type.Bounds.html b/composable/views/type.Bounds.html new file mode 100644 index 00000000..4d5d5a19 --- /dev/null +++ b/composable/views/type.Bounds.html @@ -0,0 +1,5 @@ +Bounds in composable::views - Rust

Type Alias composable::views::Bounds

pub type Bounds = Box2D<f32, UnknownUnit>;
Available on crate features unreleased and views only.
Expand description

Alias for euclid::default::Box2D<f32>

+

Aliased Type§

struct Bounds {
+    pub min: Point2D<f32, UnknownUnit>,
+    pub max: Point2D<f32, UnknownUnit>,
+}

Fields§

§min: Point2D<f32, UnknownUnit>§max: Point2D<f32, UnknownUnit>
\ No newline at end of file diff --git a/composable/views/type.Offsets.html b/composable/views/type.Offsets.html new file mode 100644 index 00000000..ada76157 --- /dev/null +++ b/composable/views/type.Offsets.html @@ -0,0 +1,7 @@ +Offsets in composable::views - Rust

Type Alias composable::views::Offsets

source ·
pub type Offsets = SideOffsets2D<f32>;
Available on crate features unreleased and views only.
Expand description

Alias for euclid::default::SideOffsets2D<f32>

+

Aliased Type§

struct Offsets {
+    pub top: f32,
+    pub right: f32,
+    pub bottom: f32,
+    pub left: f32,
+}

Fields§

§top: f32§right: f32§bottom: f32§left: f32
\ No newline at end of file diff --git a/composable/views/type.Point.html b/composable/views/type.Point.html new file mode 100644 index 00000000..f375061f --- /dev/null +++ b/composable/views/type.Point.html @@ -0,0 +1,5 @@ +Point in composable::views - Rust

Type Alias composable::views::Point

pub type Point = Point2D<f32, UnknownUnit>;
Available on crate features unreleased and views only.
Expand description

Alias for euclid::default::Point2D<f32>.

+

Aliased Type§

struct Point {
+    pub x: f32,
+    pub y: f32,
+}

Fields§

§x: f32§y: f32
\ No newline at end of file diff --git a/composable/views/type.Size.html b/composable/views/type.Size.html new file mode 100644 index 00000000..19d8f51e --- /dev/null +++ b/composable/views/type.Size.html @@ -0,0 +1,7 @@ +Size in composable::views - Rust

Type Alias composable::views::Size

pub type Size = Size2D<f32, UnknownUnit>;
Available on crate features unreleased and views only.
Expand description

Alias for euclid::default::Size2D<f32>.

+

Aliased Type§

struct Size {
+    pub width: f32,
+    pub height: f32,
+}

Fields§

§width: f32

The extent of the element in the U units along the x axis (usually horizontal).

+
§height: f32

The extent of the element in the U units along the y axis (usually vertical).

+
\ No newline at end of file diff --git a/composable/views/type.Transform.html b/composable/views/type.Transform.html new file mode 100644 index 00000000..47b21371 --- /dev/null +++ b/composable/views/type.Transform.html @@ -0,0 +1,9 @@ +Transform in composable::views - Rust

Type Alias composable::views::Transform

pub type Transform = Transform2D<f32, UnknownUnit, UnknownUnit>;
Available on crate features unreleased and views only.
Expand description

Alias for euclid::default::Transform2D<f32>

+

Aliased Type§

struct Transform {
+    pub m11: f32,
+    pub m12: f32,
+    pub m21: f32,
+    pub m22: f32,
+    pub m31: f32,
+    pub m32: f32,
+}

Fields§

§m11: f32§m12: f32§m21: f32§m22: f32§m31: f32§m32: f32
\ No newline at end of file diff --git a/composable/views/ui/accessibility/enum.Scale.html b/composable/views/ui/accessibility/enum.Scale.html new file mode 100644 index 00000000..993e2151 --- /dev/null +++ b/composable/views/ui/accessibility/enum.Scale.html @@ -0,0 +1,35 @@ +Scale in composable::views::ui::accessibility - Rust

Enum composable::views::ui::accessibility::Scale

source ·
pub enum Scale {
+    XXS,
+    XS,
+    S,
+    M,
+    L,
+    XL,
+    XXL,
+    XXXL,
+}
Available on crate features unreleased and views and default_ui only.
Expand description

Scale defines a predefined scale for scalable content.

+

Variants§

§

XXS

Use extra extra small sizes.
+This is the default on desktop platforms.

+
§

XS

use extra small sizes.

+
§

S

Use small sizes.

+
§

M

Use medium sizes.

+
§

L

Use large sizes.
+This is the default on mobile platforms.

+
§

XL

use extra large sizes.

+
§

XXL

Use extra extra large sizes.

+
§

XXXL

Use extra extra extra large sizes.

+

Implementations§

source§

impl Scale

source

pub fn scale(&self, i: f32) -> f32

Font scale per Accessibility level

+

Trait Implementations§

source§

impl Clone for Scale

source§

fn clone(&self) -> Scale

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Default for Scale

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Copy for Scale

source§

impl DependencyDefault for Scale

Auto Trait Implementations§

§

impl Freeze for Scale

§

impl RefUnwindSafe for Scale

§

impl Send for Scale

§

impl Sync for Scale

§

impl Unpin for Scale

§

impl UnwindSafe for Scale

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§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> CloneToUninit for T
where + T: Copy,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where + T: Clone,

§

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>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/accessibility/index.html b/composable/views/ui/accessibility/index.html new file mode 100644 index 00000000..e9600849 --- /dev/null +++ b/composable/views/ui/accessibility/index.html @@ -0,0 +1 @@ +composable::views::ui::accessibility - Rust

Module composable::views::ui::accessibility

source ·
Available on crate features unreleased and views and default_ui only.

Enums§

  • Scale defines a predefined scale for scalable content.
\ No newline at end of file diff --git a/composable/views/ui/accessibility/sidebar-items.js b/composable/views/ui/accessibility/sidebar-items.js new file mode 100644 index 00000000..e43567d1 --- /dev/null +++ b/composable/views/ui/accessibility/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Scale"]}; \ No newline at end of file diff --git a/composable/views/ui/colors/fn.primary_background.html b/composable/views/ui/colors/fn.primary_background.html new file mode 100644 index 00000000..237ac52e --- /dev/null +++ b/composable/views/ui/colors/fn.primary_background.html @@ -0,0 +1 @@ +primary_background in composable::views::ui::colors - Rust

Function composable::views::ui::colors::primary_background

source ·
pub fn primary_background() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.primary_content.html b/composable/views/ui/colors/fn.primary_content.html new file mode 100644 index 00000000..6f146d95 --- /dev/null +++ b/composable/views/ui/colors/fn.primary_content.html @@ -0,0 +1 @@ +primary_content in composable::views::ui::colors - Rust

Function composable::views::ui::colors::primary_content

source ·
pub fn primary_content() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.primary_shapes.html b/composable/views/ui/colors/fn.primary_shapes.html new file mode 100644 index 00000000..66667247 --- /dev/null +++ b/composable/views/ui/colors/fn.primary_shapes.html @@ -0,0 +1 @@ +primary_shapes in composable::views::ui::colors - Rust

Function composable::views::ui::colors::primary_shapes

source ·
pub fn primary_shapes() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.quaternary_background.html b/composable/views/ui/colors/fn.quaternary_background.html new file mode 100644 index 00000000..97bdadb7 --- /dev/null +++ b/composable/views/ui/colors/fn.quaternary_background.html @@ -0,0 +1 @@ +quaternary_background in composable::views::ui::colors - Rust

Function composable::views::ui::colors::quaternary_background

source ·
pub fn quaternary_background() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.quaternary_content.html b/composable/views/ui/colors/fn.quaternary_content.html new file mode 100644 index 00000000..bd76f2cb --- /dev/null +++ b/composable/views/ui/colors/fn.quaternary_content.html @@ -0,0 +1 @@ +quaternary_content in composable::views::ui::colors - Rust

Function composable::views::ui::colors::quaternary_content

source ·
pub fn quaternary_content() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.quaternary_shapes.html b/composable/views/ui/colors/fn.quaternary_shapes.html new file mode 100644 index 00000000..a273f4ff --- /dev/null +++ b/composable/views/ui/colors/fn.quaternary_shapes.html @@ -0,0 +1 @@ +quaternary_shapes in composable::views::ui::colors - Rust

Function composable::views::ui::colors::quaternary_shapes

source ·
pub fn quaternary_shapes() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.secondary_background.html b/composable/views/ui/colors/fn.secondary_background.html new file mode 100644 index 00000000..3ed2bf26 --- /dev/null +++ b/composable/views/ui/colors/fn.secondary_background.html @@ -0,0 +1 @@ +secondary_background in composable::views::ui::colors - Rust

Function composable::views::ui::colors::secondary_background

source ·
pub fn secondary_background() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.secondary_content.html b/composable/views/ui/colors/fn.secondary_content.html new file mode 100644 index 00000000..72c84e21 --- /dev/null +++ b/composable/views/ui/colors/fn.secondary_content.html @@ -0,0 +1 @@ +secondary_content in composable::views::ui::colors - Rust

Function composable::views::ui::colors::secondary_content

source ·
pub fn secondary_content() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.secondary_shapes.html b/composable/views/ui/colors/fn.secondary_shapes.html new file mode 100644 index 00000000..11b184e1 --- /dev/null +++ b/composable/views/ui/colors/fn.secondary_shapes.html @@ -0,0 +1 @@ +secondary_shapes in composable::views::ui::colors - Rust

Function composable::views::ui::colors::secondary_shapes

source ·
pub fn secondary_shapes() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.tertiary_background.html b/composable/views/ui/colors/fn.tertiary_background.html new file mode 100644 index 00000000..a3cb7207 --- /dev/null +++ b/composable/views/ui/colors/fn.tertiary_background.html @@ -0,0 +1 @@ +tertiary_background in composable::views::ui::colors - Rust

Function composable::views::ui::colors::tertiary_background

source ·
pub fn tertiary_background() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.tertiary_content.html b/composable/views/ui/colors/fn.tertiary_content.html new file mode 100644 index 00000000..308f6b5d --- /dev/null +++ b/composable/views/ui/colors/fn.tertiary_content.html @@ -0,0 +1 @@ +tertiary_content in composable::views::ui::colors - Rust

Function composable::views::ui::colors::tertiary_content

source ·
pub fn tertiary_content() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/fn.tertiary_shapes.html b/composable/views/ui/colors/fn.tertiary_shapes.html new file mode 100644 index 00000000..301d16e9 --- /dev/null +++ b/composable/views/ui/colors/fn.tertiary_shapes.html @@ -0,0 +1 @@ +tertiary_shapes in composable::views::ui::colors - Rust

Function composable::views::ui::colors::tertiary_shapes

source ·
pub fn tertiary_shapes() -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/colors/gray/fn.background.html b/composable/views/ui/colors/gray/fn.background.html new file mode 100644 index 00000000..77657b3b --- /dev/null +++ b/composable/views/ui/colors/gray/fn.background.html @@ -0,0 +1,2 @@ +background in composable::views::ui::colors::gray - Rust

Function composable::views::ui::colors::gray::background

source ·
pub const fn background(brightness: u8) -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
Expand description

Gray wih a noticable blue tint

+
\ No newline at end of file diff --git a/composable/views/ui/colors/gray/fn.foreground.html b/composable/views/ui/colors/gray/fn.foreground.html new file mode 100644 index 00000000..fe455f64 --- /dev/null +++ b/composable/views/ui/colors/gray/fn.foreground.html @@ -0,0 +1,2 @@ +foreground in composable::views::ui::colors::gray - Rust

Function composable::views::ui::colors::gray::foreground

source ·
pub const fn foreground(brightness: u8) -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
Expand description

Gray with a subtle blue tint

+
\ No newline at end of file diff --git a/composable/views/ui/colors/gray/fn.pure.html b/composable/views/ui/colors/gray/fn.pure.html new file mode 100644 index 00000000..57f643a2 --- /dev/null +++ b/composable/views/ui/colors/gray/fn.pure.html @@ -0,0 +1,2 @@ +pure in composable::views::ui::colors::gray - Rust

Function composable::views::ui::colors::gray::pure

source ·
pub const fn pure(brightness: u8) -> [u8; 4]
Available on crate features unreleased and views and default_ui only.
Expand description

Gray with no tint; pure grays

+
\ No newline at end of file diff --git a/composable/views/ui/colors/gray/index.html b/composable/views/ui/colors/gray/index.html new file mode 100644 index 00000000..6577b9e3 --- /dev/null +++ b/composable/views/ui/colors/gray/index.html @@ -0,0 +1,7 @@ +composable::views::ui::colors::gray - Rust

Module composable::views::ui::colors::gray

source ·
Available on crate features unreleased and views and default_ui only.
Expand description

Shades of gray; where

+
    +
  • zero is black,
  • +
  • sixteen is white, with
  • +
  • fifteen shades of gray in between.
  • +
+

Functions§

\ No newline at end of file diff --git a/composable/views/ui/colors/gray/sidebar-items.js b/composable/views/ui/colors/gray/sidebar-items.js new file mode 100644 index 00000000..56409107 --- /dev/null +++ b/composable/views/ui/colors/gray/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["background","foreground","pure"]}; \ No newline at end of file diff --git a/composable/views/ui/colors/index.html b/composable/views/ui/colors/index.html new file mode 100644 index 00000000..78dc84e6 --- /dev/null +++ b/composable/views/ui/colors/index.html @@ -0,0 +1 @@ +composable::views::ui::colors - Rust

Module composable::views::ui::colors

source ·
Available on crate features unreleased and views and default_ui only.

Modules§

  • Shades of gray; where

Functions§

\ No newline at end of file diff --git a/composable/views/ui/colors/sidebar-items.js b/composable/views/ui/colors/sidebar-items.js new file mode 100644 index 00000000..074601c9 --- /dev/null +++ b/composable/views/ui/colors/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["primary_background","primary_content","primary_shapes","quaternary_background","quaternary_content","quaternary_shapes","secondary_background","secondary_content","secondary_shapes","tertiary_background","tertiary_content","tertiary_shapes"],"mod":["gray"]}; \ No newline at end of file diff --git a/composable/views/ui/font/body/index.html b/composable/views/ui/font/body/index.html new file mode 100644 index 00000000..bffdfcef --- /dev/null +++ b/composable/views/ui/font/body/index.html @@ -0,0 +1,2 @@ +composable::views::ui::font::body - Rust

Module composable::views::ui::font::body

source ·
Available on crate features unreleased and views and default_ui only.
Expand description

Body Font styles.

+

Structs§

  • Large variant
  • Medium variant
  • Small variant
\ No newline at end of file diff --git a/composable/views/ui/font/body/sidebar-items.js b/composable/views/ui/font/body/sidebar-items.js new file mode 100644 index 00000000..5bfc1cbb --- /dev/null +++ b/composable/views/ui/font/body/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["L","M","S"]}; \ No newline at end of file diff --git a/composable/views/ui/font/body/struct.L.html b/composable/views/ui/font/body/struct.L.html new file mode 100644 index 00000000..3d043c9d --- /dev/null +++ b/composable/views/ui/font/body/struct.L.html @@ -0,0 +1,12 @@ +L in composable::views::ui::font::body - Rust

Struct composable::views::ui::font::body::L

source ·
pub struct L;
Available on crate features unreleased and views and default_ui only.
Expand description

Large variant

+

Auto Trait Implementations§

§

impl Freeze for L

§

impl RefUnwindSafe for L

§

impl Send for L

§

impl Sync for L

§

impl Unpin for L

§

impl UnwindSafe for L

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/body/struct.M.html b/composable/views/ui/font/body/struct.M.html new file mode 100644 index 00000000..ae3ad83a --- /dev/null +++ b/composable/views/ui/font/body/struct.M.html @@ -0,0 +1,12 @@ +M in composable::views::ui::font::body - Rust

Struct composable::views::ui::font::body::M

source ·
pub struct M;
Available on crate features unreleased and views and default_ui only.
Expand description

Medium variant

+

Auto Trait Implementations§

§

impl Freeze for M

§

impl RefUnwindSafe for M

§

impl Send for M

§

impl Sync for M

§

impl Unpin for M

§

impl UnwindSafe for M

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/body/struct.S.html b/composable/views/ui/font/body/struct.S.html new file mode 100644 index 00000000..70fb8c43 --- /dev/null +++ b/composable/views/ui/font/body/struct.S.html @@ -0,0 +1,12 @@ +S in composable::views::ui::font::body - Rust

Struct composable::views::ui::font::body::S

source ·
pub struct S;
Available on crate features unreleased and views and default_ui only.
Expand description

Small variant

+

Auto Trait Implementations§

§

impl Freeze for S

§

impl RefUnwindSafe for S

§

impl Send for S

§

impl Sync for S

§

impl Unpin for S

§

impl UnwindSafe for S

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/fn.with_default_fonts.html b/composable/views/ui/font/fn.with_default_fonts.html new file mode 100644 index 00000000..f8dae208 --- /dev/null +++ b/composable/views/ui/font/fn.with_default_fonts.html @@ -0,0 +1,2 @@ +with_default_fonts in composable::views::ui::font - Rust

Function composable::views::ui::font::with_default_fonts

source ·
pub fn with_default_fonts<F: FnOnce() -> R, R>(f: F) -> R
Available on crate features unreleased and views and default_ui only.
Expand description

Sets the default font for the supplied closure.

+
\ No newline at end of file diff --git a/composable/views/ui/font/index.html b/composable/views/ui/font/index.html new file mode 100644 index 00000000..04a1f06b --- /dev/null +++ b/composable/views/ui/font/index.html @@ -0,0 +1,2 @@ +composable::views::ui::font - Rust

Module composable::views::ui::font

source ·
Available on crate features unreleased and views and default_ui only.
Expand description

Minimal Font handling.

+

Modules§

Structs§

Functions§

\ No newline at end of file diff --git a/composable/views/ui/font/label/index.html b/composable/views/ui/font/label/index.html new file mode 100644 index 00000000..14754acc --- /dev/null +++ b/composable/views/ui/font/label/index.html @@ -0,0 +1,2 @@ +composable::views::ui::font::label - Rust

Module composable::views::ui::font::label

source ·
Available on crate features unreleased and views and default_ui only.
Expand description

Label Font styles.

+

Structs§

  • Large variant
  • Medium variant
  • Small variant
\ No newline at end of file diff --git a/composable/views/ui/font/label/sidebar-items.js b/composable/views/ui/font/label/sidebar-items.js new file mode 100644 index 00000000..5bfc1cbb --- /dev/null +++ b/composable/views/ui/font/label/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["L","M","S"]}; \ No newline at end of file diff --git a/composable/views/ui/font/label/struct.L.html b/composable/views/ui/font/label/struct.L.html new file mode 100644 index 00000000..7ede94dd --- /dev/null +++ b/composable/views/ui/font/label/struct.L.html @@ -0,0 +1,12 @@ +L in composable::views::ui::font::label - Rust

Struct composable::views::ui::font::label::L

source ·
pub struct L;
Available on crate features unreleased and views and default_ui only.
Expand description

Large variant

+

Auto Trait Implementations§

§

impl Freeze for L

§

impl RefUnwindSafe for L

§

impl Send for L

§

impl Sync for L

§

impl Unpin for L

§

impl UnwindSafe for L

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/label/struct.M.html b/composable/views/ui/font/label/struct.M.html new file mode 100644 index 00000000..a85f3685 --- /dev/null +++ b/composable/views/ui/font/label/struct.M.html @@ -0,0 +1,12 @@ +M in composable::views::ui::font::label - Rust

Struct composable::views::ui::font::label::M

source ·
pub struct M;
Available on crate features unreleased and views and default_ui only.
Expand description

Medium variant

+

Auto Trait Implementations§

§

impl Freeze for M

§

impl RefUnwindSafe for M

§

impl Send for M

§

impl Sync for M

§

impl Unpin for M

§

impl UnwindSafe for M

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/label/struct.S.html b/composable/views/ui/font/label/struct.S.html new file mode 100644 index 00000000..62a416a6 --- /dev/null +++ b/composable/views/ui/font/label/struct.S.html @@ -0,0 +1,12 @@ +S in composable::views::ui::font::label - Rust

Struct composable::views::ui::font::label::S

source ·
pub struct S;
Available on crate features unreleased and views and default_ui only.
Expand description

Small variant

+

Auto Trait Implementations§

§

impl Freeze for S

§

impl RefUnwindSafe for S

§

impl Send for S

§

impl Sync for S

§

impl Unpin for S

§

impl UnwindSafe for S

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/sidebar-items.js b/composable/views/ui/font/sidebar-items.js new file mode 100644 index 00000000..f9321a2e --- /dev/null +++ b/composable/views/ui/font/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["with_default_fonts"],"mod":["body","label","title"],"struct":["Inter"]}; \ No newline at end of file diff --git a/composable/views/ui/font/struct.Inter.html b/composable/views/ui/font/struct.Inter.html new file mode 100644 index 00000000..d453d787 --- /dev/null +++ b/composable/views/ui/font/struct.Inter.html @@ -0,0 +1,42 @@ +Inter in composable::views::ui::font - Rust

Struct composable::views::ui::font::Inter

source ·
pub struct Inter<'a, Style> { /* private fields */ }
Available on crate features unreleased and views and default_ui only.
Expand description

The Inter font

+
+

§Inter

+

Inter is a typeface carefully crafted & designed for computer screens. +Inter features a tall x-height to aid in readability of mixed-case and +lower-case text. +Inter is a variable font with +several OpenType features, +like contextual alternates that adjusts punctuation depending on the shape +of surrounding glyphs, slashed zero for when you need to disambiguate +“0” from “o”, tabular numbers, etc.

+
+

Sample

+
+

Release 4.0

+

Methods from Deref<Target = Font<'a>>§

source

pub fn full_name(&self) -> Option<String>

Full font name that reflects all family and relevant subfamily descriptors.

+
source

pub fn family(&self) -> Option<String>

Family name.

+
source

pub fn style(&self) -> Option<String>

Subfamily name.

+
source

pub fn identifier(&self) -> Option<String>

Unique font identifier

+
source

pub fn version(&self) -> Option<String>

Should begin with the syntax “Version N.M” +(upper case, lower case, or mixed, with a space between “Version” and the number).

+
source

pub fn size(&self) -> f32

Font size in points.

+
source

pub fn ascender(&self) -> f32

Horizontal face ascender.

+
source

pub fn descender(&self) -> f32

Horizontal face descender,

+
source

pub fn height(&self) -> f32

Horizontal height,

+
source

pub fn capital_height(&self) -> f32

Capital height,

+
source

pub fn line_gap(&self) -> f32

Line gap,

+
source

pub fn text(&self, rgba: [u8; 4], string: &str) -> Text<'_>

Returns a Text in this font.

+

Trait Implementations§

source§

impl Default for Inter<'static, L>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, L>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, L>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, M>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, M>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, M>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, S>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, S>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Default for Inter<'static, S>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<'a, Style> Deref for Inter<'a, Style>

§

type Target = Font<'a>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DependencyDefault for Inter<'static, L>

source§

impl DependencyDefault for Inter<'static, L>

source§

impl DependencyDefault for Inter<'static, L>

source§

impl DependencyDefault for Inter<'static, M>

source§

impl DependencyDefault for Inter<'static, M>

source§

impl DependencyDefault for Inter<'static, M>

source§

impl DependencyDefault for Inter<'static, S>

source§

impl DependencyDefault for Inter<'static, S>

source§

impl DependencyDefault for Inter<'static, S>

Auto Trait Implementations§

§

impl<'a, Style> Freeze for Inter<'a, Style>

§

impl<'a, Style> !RefUnwindSafe for Inter<'a, Style>

§

impl<'a, Style> Send for Inter<'a, Style>
where + Style: Send,

§

impl<'a, Style> Sync for Inter<'a, Style>
where + Style: Sync,

§

impl<'a, Style> Unpin for Inter<'a, Style>
where + Style: Unpin,

§

impl<'a, Style> !UnwindSafe for Inter<'a, Style>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/title/index.html b/composable/views/ui/font/title/index.html new file mode 100644 index 00000000..77312f23 --- /dev/null +++ b/composable/views/ui/font/title/index.html @@ -0,0 +1,2 @@ +composable::views::ui::font::title - Rust

Module composable::views::ui::font::title

source ·
Available on crate features unreleased and views and default_ui only.
Expand description

Title Font styles.

+

Structs§

  • Large variant
  • Medium variant
  • Small variant
\ No newline at end of file diff --git a/composable/views/ui/font/title/sidebar-items.js b/composable/views/ui/font/title/sidebar-items.js new file mode 100644 index 00000000..5bfc1cbb --- /dev/null +++ b/composable/views/ui/font/title/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["L","M","S"]}; \ No newline at end of file diff --git a/composable/views/ui/font/title/struct.L.html b/composable/views/ui/font/title/struct.L.html new file mode 100644 index 00000000..bb7b687c --- /dev/null +++ b/composable/views/ui/font/title/struct.L.html @@ -0,0 +1,12 @@ +L in composable::views::ui::font::title - Rust

Struct composable::views::ui::font::title::L

source ·
pub struct L;
Available on crate features unreleased and views and default_ui only.
Expand description

Large variant

+

Auto Trait Implementations§

§

impl Freeze for L

§

impl RefUnwindSafe for L

§

impl Send for L

§

impl Sync for L

§

impl Unpin for L

§

impl UnwindSafe for L

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/title/struct.M.html b/composable/views/ui/font/title/struct.M.html new file mode 100644 index 00000000..92d62622 --- /dev/null +++ b/composable/views/ui/font/title/struct.M.html @@ -0,0 +1,12 @@ +M in composable::views::ui::font::title - Rust

Struct composable::views::ui::font::title::M

source ·
pub struct M;
Available on crate features unreleased and views and default_ui only.
Expand description

Medium variant

+

Auto Trait Implementations§

§

impl Freeze for M

§

impl RefUnwindSafe for M

§

impl Send for M

§

impl Sync for M

§

impl Unpin for M

§

impl UnwindSafe for M

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/title/struct.S.html b/composable/views/ui/font/title/struct.S.html new file mode 100644 index 00000000..efcd36d4 --- /dev/null +++ b/composable/views/ui/font/title/struct.S.html @@ -0,0 +1,12 @@ +S in composable::views::ui::font::title - Rust

Struct composable::views::ui::font::title::S

source ·
pub struct S;
Available on crate features unreleased and views and default_ui only.
Expand description

Small variant

+

Auto Trait Implementations§

§

impl Freeze for S

§

impl RefUnwindSafe for S

§

impl Send for S

§

impl Sync for S

§

impl Unpin for S

§

impl UnwindSafe for S

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.
\ No newline at end of file diff --git a/composable/views/ui/font/typography/body/index.html b/composable/views/ui/font/typography/body/index.html new file mode 100644 index 00000000..3685dc8f --- /dev/null +++ b/composable/views/ui/font/typography/body/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/body/index.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/body/struct.L.html b/composable/views/ui/font/typography/body/struct.L.html new file mode 100644 index 00000000..47fe780b --- /dev/null +++ b/composable/views/ui/font/typography/body/struct.L.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/body/struct.L.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/body/struct.M.html b/composable/views/ui/font/typography/body/struct.M.html new file mode 100644 index 00000000..6cb8e8ed --- /dev/null +++ b/composable/views/ui/font/typography/body/struct.M.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/body/struct.M.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/body/struct.S.html b/composable/views/ui/font/typography/body/struct.S.html new file mode 100644 index 00000000..23b45b84 --- /dev/null +++ b/composable/views/ui/font/typography/body/struct.S.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/body/struct.S.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/label/index.html b/composable/views/ui/font/typography/label/index.html new file mode 100644 index 00000000..89532af7 --- /dev/null +++ b/composable/views/ui/font/typography/label/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/label/index.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/label/struct.L.html b/composable/views/ui/font/typography/label/struct.L.html new file mode 100644 index 00000000..97626dd3 --- /dev/null +++ b/composable/views/ui/font/typography/label/struct.L.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/label/struct.L.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/label/struct.M.html b/composable/views/ui/font/typography/label/struct.M.html new file mode 100644 index 00000000..afeb4950 --- /dev/null +++ b/composable/views/ui/font/typography/label/struct.M.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/label/struct.M.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/label/struct.S.html b/composable/views/ui/font/typography/label/struct.S.html new file mode 100644 index 00000000..05e623f9 --- /dev/null +++ b/composable/views/ui/font/typography/label/struct.S.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/label/struct.S.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/title/index.html b/composable/views/ui/font/typography/title/index.html new file mode 100644 index 00000000..ade1f4ff --- /dev/null +++ b/composable/views/ui/font/typography/title/index.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/title/index.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/title/struct.L.html b/composable/views/ui/font/typography/title/struct.L.html new file mode 100644 index 00000000..bf78eb1c --- /dev/null +++ b/composable/views/ui/font/typography/title/struct.L.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/title/struct.L.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/title/struct.M.html b/composable/views/ui/font/typography/title/struct.M.html new file mode 100644 index 00000000..0f0dea12 --- /dev/null +++ b/composable/views/ui/font/typography/title/struct.M.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/title/struct.M.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/font/typography/title/struct.S.html b/composable/views/ui/font/typography/title/struct.S.html new file mode 100644 index 00000000..2dcdf424 --- /dev/null +++ b/composable/views/ui/font/typography/title/struct.S.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../../../composable/views/ui/font/title/struct.S.html...

+ + + \ No newline at end of file diff --git a/composable/views/ui/index.html b/composable/views/ui/index.html new file mode 100644 index 00000000..42689823 --- /dev/null +++ b/composable/views/ui/index.html @@ -0,0 +1,19 @@ +composable::views::ui - Rust

Module composable::views::ui

source ·
Available on crate features unreleased and views and default_ui only.
Expand description

A minimal, but viable, user interface layer.

+

§Minimal

+

Minimal exist as a separate feature so that applications that need +completely custom user interface elements are not weighted down by the +implementations here; while still having access to those same interface +elements to use as reference when building their own.

+
    +
  • Configurable
    +Much of the design of Minimal’s user interface elements has been +configured via dependencies as default values. As such they can be +overridden by the applications as needed.
  • +
  • Incremental
    +Furthermore, use of Minimal does not need to be all or nothing. +Development of an application can begin with Minimal’s default +look-and-feel and custom View implementations can be added +incrementally to the application as its configurability becomes +insufficient.
  • +
+

Re-exports§

Modules§

\ No newline at end of file diff --git a/composable/views/ui/sidebar-items.js b/composable/views/ui/sidebar-items.js new file mode 100644 index 00000000..b1e1765d --- /dev/null +++ b/composable/views/ui/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["accessibility","colors","font","spacer","spacing"]}; \ No newline at end of file diff --git a/composable/views/ui/spacer/fn.L.html b/composable/views/ui/spacer/fn.L.html new file mode 100644 index 00000000..278dfdc4 --- /dev/null +++ b/composable/views/ui/spacer/fn.L.html @@ -0,0 +1 @@ +L in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::L

source ·
pub fn L() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.M.html b/composable/views/ui/spacer/fn.M.html new file mode 100644 index 00000000..7dd4e837 --- /dev/null +++ b/composable/views/ui/spacer/fn.M.html @@ -0,0 +1 @@ +M in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::M

source ·
pub fn M() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.S.html b/composable/views/ui/spacer/fn.S.html new file mode 100644 index 00000000..dd8b1d2a --- /dev/null +++ b/composable/views/ui/spacer/fn.S.html @@ -0,0 +1 @@ +S in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::S

source ·
pub fn S() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.XL.html b/composable/views/ui/spacer/fn.XL.html new file mode 100644 index 00000000..cac446d7 --- /dev/null +++ b/composable/views/ui/spacer/fn.XL.html @@ -0,0 +1 @@ +XL in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::XL

source ·
pub fn XL() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.XS.html b/composable/views/ui/spacer/fn.XS.html new file mode 100644 index 00000000..d6a32ba8 --- /dev/null +++ b/composable/views/ui/spacer/fn.XS.html @@ -0,0 +1 @@ +XS in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::XS

source ·
pub fn XS() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.XXL.html b/composable/views/ui/spacer/fn.XXL.html new file mode 100644 index 00000000..988c4d3c --- /dev/null +++ b/composable/views/ui/spacer/fn.XXL.html @@ -0,0 +1 @@ +XXL in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::XXL

source ·
pub fn XXL() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.XXS.html b/composable/views/ui/spacer/fn.XXS.html new file mode 100644 index 00000000..587532c2 --- /dev/null +++ b/composable/views/ui/spacer/fn.XXS.html @@ -0,0 +1 @@ +XXS in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::XXS

source ·
pub fn XXS() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.XXXL.html b/composable/views/ui/spacer/fn.XXXL.html new file mode 100644 index 00000000..25106110 --- /dev/null +++ b/composable/views/ui/spacer/fn.XXXL.html @@ -0,0 +1 @@ +XXXL in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::XXXL

source ·
pub fn XXXL() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.default.html b/composable/views/ui/spacer/fn.default.html new file mode 100644 index 00000000..89e669a1 --- /dev/null +++ b/composable/views/ui/spacer/fn.default.html @@ -0,0 +1 @@ +default in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::default

source ·
pub fn default() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.empty.html b/composable/views/ui/spacer/fn.empty.html new file mode 100644 index 00000000..7a63529b --- /dev/null +++ b/composable/views/ui/spacer/fn.empty.html @@ -0,0 +1 @@ +empty in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::empty

source ·
pub fn empty() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.fill.html b/composable/views/ui/spacer/fn.fill.html new file mode 100644 index 00000000..b0d6891a --- /dev/null +++ b/composable/views/ui/spacer/fn.fill.html @@ -0,0 +1 @@ +fill in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::fill

source ·
pub fn fill() -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.fixed.html b/composable/views/ui/spacer/fn.fixed.html new file mode 100644 index 00000000..b82263a7 --- /dev/null +++ b/composable/views/ui/spacer/fn.fixed.html @@ -0,0 +1 @@ +fixed in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::fixed

source ·
pub fn fixed(width: f32, height: f32) -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.height.html b/composable/views/ui/spacer/fn.height.html new file mode 100644 index 00000000..54ec20b6 --- /dev/null +++ b/composable/views/ui/spacer/fn.height.html @@ -0,0 +1 @@ +height in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::height

source ·
pub fn height(height: f32) -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/fn.width.html b/composable/views/ui/spacer/fn.width.html new file mode 100644 index 00000000..c26be4d0 --- /dev/null +++ b/composable/views/ui/spacer/fn.width.html @@ -0,0 +1 @@ +width in composable::views::ui::spacer - Rust

Function composable::views::ui::spacer::width

source ·
pub fn width(width: f32) -> Spacer
Available on crate features unreleased and views and default_ui only.
\ No newline at end of file diff --git a/composable/views/ui/spacer/index.html b/composable/views/ui/spacer/index.html new file mode 100644 index 00000000..c56525f3 --- /dev/null +++ b/composable/views/ui/spacer/index.html @@ -0,0 +1 @@ +composable::views::ui::spacer - Rust

Module composable::views::ui::spacer

source ·
Available on crate features unreleased and views and default_ui only.

Modules§

Functions§

\ No newline at end of file diff --git a/composable/views/ui/spacer/sidebar-items.js b/composable/views/ui/spacer/sidebar-items.js new file mode 100644 index 00000000..fa2e839a --- /dev/null +++ b/composable/views/ui/spacer/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["L","M","S","XL","XS","XXL","XXS","XXXL","default","empty","fill","fixed","height","width"],"mod":["spacing"]}; \ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.L.html b/composable/views/ui/spacer/spacing/constant.L.html new file mode 100644 index 00000000..bf7f5fe3 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.L.html @@ -0,0 +1,5 @@ +L in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::L

source ·
pub const L: f32 = 28.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::L()

+ +
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.M.html b/composable/views/ui/spacer/spacing/constant.M.html new file mode 100644 index 00000000..a0387dc0 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.M.html @@ -0,0 +1,5 @@ +M in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::M

source ·
pub const M: f32 = 18.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::M()

+
    +
  • A good minimum target size for trackpads/mice
  • +
+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.S.html b/composable/views/ui/spacer/spacing/constant.S.html new file mode 100644 index 00000000..d080d9bf --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.S.html @@ -0,0 +1,2 @@ +S in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::S

source ·
pub const S: f32 = 8.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::S()

+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.XL.html b/composable/views/ui/spacer/spacing/constant.XL.html new file mode 100644 index 00000000..e924c003 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.XL.html @@ -0,0 +1,2 @@ +XL in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::XL

source ·
pub const XL: f32 = 38.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XL()

+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.XS.html b/composable/views/ui/spacer/spacing/constant.XS.html new file mode 100644 index 00000000..77540698 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.XS.html @@ -0,0 +1,2 @@ +XS in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::XS

source ·
pub const XS: f32 = 4.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XS()

+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.XXL.html b/composable/views/ui/spacer/spacing/constant.XXL.html new file mode 100644 index 00000000..31364b21 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.XXL.html @@ -0,0 +1,5 @@ +XXL in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::XXL

source ·
pub const XXL: f32 = 48.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XXL()

+
    +
  • A good minimum target size for tablets/phones/touchscreen
  • +
+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.XXS.html b/composable/views/ui/spacer/spacing/constant.XXS.html new file mode 100644 index 00000000..424f8422 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.XXS.html @@ -0,0 +1,2 @@ +XXS in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::XXS

source ·
pub const XXS: f32 = 2.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XXS()

+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/constant.XXXL.html b/composable/views/ui/spacer/spacing/constant.XXXL.html new file mode 100644 index 00000000..2e34edc4 --- /dev/null +++ b/composable/views/ui/spacer/spacing/constant.XXXL.html @@ -0,0 +1,2 @@ +XXXL in composable::views::ui::spacer::spacing - Rust

Constant composable::views::ui::spacer::spacing::XXXL

source ·
pub const XXXL: f32 = 58.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XXXL()

+
\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/index.html b/composable/views/ui/spacer/spacing/index.html new file mode 100644 index 00000000..28cce695 --- /dev/null +++ b/composable/views/ui/spacer/spacing/index.html @@ -0,0 +1 @@ +composable::views::ui::spacer::spacing - Rust

Module composable::views::ui::spacer::spacing

source ·
Available on crate features unreleased and views and default_ui only.

Constants§

\ No newline at end of file diff --git a/composable/views/ui/spacer/spacing/sidebar-items.js b/composable/views/ui/spacer/spacing/sidebar-items.js new file mode 100644 index 00000000..cd8f40c1 --- /dev/null +++ b/composable/views/ui/spacer/spacing/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["L","M","S","XL","XS","XXL","XXS","XXXL"]}; \ No newline at end of file diff --git a/composable/views/ui/spacing/constant.L.html b/composable/views/ui/spacing/constant.L.html new file mode 100644 index 00000000..b5cf652d --- /dev/null +++ b/composable/views/ui/spacing/constant.L.html @@ -0,0 +1,5 @@ +L in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::L

source ·
pub const L: f32 = 28.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::L()

+ +
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.M.html b/composable/views/ui/spacing/constant.M.html new file mode 100644 index 00000000..fcf4dc85 --- /dev/null +++ b/composable/views/ui/spacing/constant.M.html @@ -0,0 +1,5 @@ +M in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::M

source ·
pub const M: f32 = 18.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::M()

+
    +
  • A good minimum target size for trackpads/mice
  • +
+
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.S.html b/composable/views/ui/spacing/constant.S.html new file mode 100644 index 00000000..853b6a9f --- /dev/null +++ b/composable/views/ui/spacing/constant.S.html @@ -0,0 +1,2 @@ +S in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::S

source ·
pub const S: f32 = 8.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::S()

+
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.XL.html b/composable/views/ui/spacing/constant.XL.html new file mode 100644 index 00000000..60606efe --- /dev/null +++ b/composable/views/ui/spacing/constant.XL.html @@ -0,0 +1,2 @@ +XL in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::XL

source ·
pub const XL: f32 = 38.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XL()

+
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.XS.html b/composable/views/ui/spacing/constant.XS.html new file mode 100644 index 00000000..2d94abc2 --- /dev/null +++ b/composable/views/ui/spacing/constant.XS.html @@ -0,0 +1,2 @@ +XS in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::XS

source ·
pub const XS: f32 = 4.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XS()

+
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.XXL.html b/composable/views/ui/spacing/constant.XXL.html new file mode 100644 index 00000000..64015470 --- /dev/null +++ b/composable/views/ui/spacing/constant.XXL.html @@ -0,0 +1,5 @@ +XXL in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::XXL

source ·
pub const XXL: f32 = 48.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XXL()

+
    +
  • A good minimum target size for tablets/phones/touchscreen
  • +
+
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.XXS.html b/composable/views/ui/spacing/constant.XXS.html new file mode 100644 index 00000000..206e1012 --- /dev/null +++ b/composable/views/ui/spacing/constant.XXS.html @@ -0,0 +1,2 @@ +XXS in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::XXS

source ·
pub const XXS: f32 = 2.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XXS()

+
\ No newline at end of file diff --git a/composable/views/ui/spacing/constant.XXXL.html b/composable/views/ui/spacing/constant.XXXL.html new file mode 100644 index 00000000..136d6f19 --- /dev/null +++ b/composable/views/ui/spacing/constant.XXXL.html @@ -0,0 +1,2 @@ +XXXL in composable::views::ui::spacing - Rust

Constant composable::views::ui::spacing::XXXL

source ·
pub const XXXL: f32 = 58.0;
Available on crate features unreleased and views and default_ui only.
Expand description

The amount of space taken up by a spacer::XXXL()

+
\ No newline at end of file diff --git a/composable/views/ui/spacing/index.html b/composable/views/ui/spacing/index.html new file mode 100644 index 00000000..2077b71f --- /dev/null +++ b/composable/views/ui/spacing/index.html @@ -0,0 +1 @@ +composable::views::ui::spacing - Rust

Module composable::views::ui::spacing

source ·
Available on crate features unreleased and views and default_ui only.

Constants§

\ No newline at end of file diff --git a/composable/views/ui/spacing/sidebar-items.js b/composable/views/ui/spacing/sidebar-items.js new file mode 100644 index 00000000..cd8f40c1 --- /dev/null +++ b/composable/views/ui/spacing/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["L","M","S","XL","XS","XXL","XXS","XXXL"]}; \ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 00000000..88e1b0ac --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["composable"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 00000000..c72e3860 --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Help

Rustdoc help

Back
\ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..1364e23b --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + diff --git a/search-index.js b/search-index.js new file mode 100644 index 00000000..0addaae4 --- /dev/null +++ b/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = new Map(JSON.parse('[\ +["composable",{"t":"RKGPRKFFKFPMNNNNNNNNNNCCNNCNNNNNNNNNNNMNNNNNNNNNNNCNNNFKNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHHNREKYEMRRKGPKFPNNNNNNNNNNNNNNMNNMNNNNNNPIFFFPGFFFGPPIKFKIFPPFEIFFIKNNMNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNMNMNMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCNNNONNNNNNNNNNNNONMOOOOOOOONNNNNNNNNMOOOONMNNNNNCCNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNOOOOOOOOPPPPPFGIPPFONNNNNNNNNNNNNNNNNNNNNNNONNNONNNHNNNNNNNNNNNNFNNNNNNNNNNNNNNFNNNNNNNNNNNNNNPGFFFPFPPFPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNECCCCCEPPPGPPPPPNNNNNNNNNNNNNNCHHHHHHHHHHHHHHHFCNNNNNNNNNNNNNNCCNNNHFFFNNNNNNNNNNNNNNNNNNNNNFFFNNNNNNNNNNNNNNNNNNNNNFFFNNNNNNNNNNNNNNNNNNNNNHHHHHHHHHHHHHCHSSSSSSSSSSSSSSSS","n":["Action","Effects","Interval","Leading","Output","Reducer","Store","Task","TestClock","TestStore","Trailing","advance","advance","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","cancel","default","default","dependencies","derive_macros","detach","drop","effects","from","from","from","into","into","into","into_inner","into_inner","new","new","recv","reduce","send","send","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","views","wait","with_initial","with_initial","Dependency","DependencyDefault","and","and_then","as_deref","as_ref","as_slice","borrow","borrow","borrow_mut","cloned","copied","default","deref","expect","filter","from","inspect","into","is_none","is_some","is_some_and","iter","map","map_or","map_or_else","new","ok_or","ok_or_else","or","or_else","static_ref","try_from","try_into","type_id","unwrap","unwrap_or","unwrap_or_default","unwrap_or_else","with_dependencies","with_dependency","xor","Action","From","RecursiveReducer","RecursiveReducer","TryInto","reduce","Action","Action","Effects","Interval","Leading","Scheduler","Scoped","Trailing","after","at","borrow","borrow_mut","clone","clone_into","clone_to_uninit","debounce","duration","every","from","future","into","scope","send","send","stream","task","task","throttle","to_owned","try_from","try_into","type_id","Began","Bounds","Circle","ContinuousRoundedRectangle","Ellipse","Ended","Event","Fixed","FixedHeight","FixedWidth","Gesture","Gesture","Moved","Offsets","Output","Padding","Path","Point","Rectangle","Redraw","Resize","RoundedRectangle","Shape","Size","Spacer","Text","Transform","View","across","ascender","begin","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","bottom","capital_height","clone","clone","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","close","continuous","cubic_bezier_to","descender","draw","draw","draw","draw","draw","draw","draw","draw","draw","draw","draw","draw","empty","event","event","event","event","event","fill","fill","fill","fixed","fixed","fixed","fixed","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","gesture","gpu","height","height","height","height","into","into","into","into","into","into","into","into","into","into","into","into","left","line_gap","line_to","m11","m12","m21","m22","m31","m32","max","min","padding","padding_all","padding_both","padding_bottom","padding_horizontal","padding_left","padding_right","padding_top","padding_vertical","quadratic_bezier_to","rgba","rgba","rgba","right","rounded","size","size","size","size","size","size","svg","text","to_owned","to_owned","top","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","ui","width","width","width","x","y","height","width","n","n","n","DownInside","DragEnter","DragExit","DragInside","DragOutside","Id","Response","State","UpInside","UpOutside","Values","active","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","default","eq","eq","eq","fmt","focus","from","from","from","hover","into","into","into","recognizer","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","Output","begin","borrow","borrow_mut","close","cubic_bezier_to","from","into","into_inner","line_to","new","quadratic_bezier_to","try_from","try_into","type_id","Output","begin","borrow","borrow_mut","close","cubic_bezier_to","from","into","into_inner","line_to","new","quadratic_bezier_to","try_from","try_into","type_id","BottomToTop","Direction","Font","FontConfig","Glyphs","Invalid","Language","LeftToRight","RightToLeft","Script","TopToBottom","as_str","ascender","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","capital_height","clear","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","clone_to_uninit","cmp","default","descender","direction","eq","eq","eq","family","feature","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from_collection","from_iso15924_tag","from_str","from_str","from_str","full_name","glyph_infos","glyph_positions","hash","hash","hash","height","identifier","into","into","into","into","into","into","is_empty","language","len","line_gap","partial_cmp","script","serialize","size","size","style","tag","text","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","version","weight","Inter","accessibility","colors","font","spacer","spacing","with_default_fonts","L","M","S","Scale","XL","XS","XXL","XXS","XXXL","borrow","borrow_mut","clone","clone_into","clone_to_uninit","clone_to_uninit","default","from","into","scale","to_owned","try_from","try_into","type_id","gray","primary_background","primary_content","primary_shapes","quaternary_background","quaternary_content","quaternary_shapes","secondary_background","secondary_content","secondary_shapes","tertiary_background","tertiary_content","tertiary_shapes","background","foreground","pure","Inter","body","borrow","borrow_mut","default","default","default","default","default","default","default","default","default","deref","from","into","label","title","try_from","try_into","type_id","with_default_fonts","L","M","S","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","from","from","from","into","into","into","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","L","M","S","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","from","from","from","into","into","into","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","L","M","S","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","from","from","from","into","into","into","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","L","M","S","XL","XS","XXL","XXS","XXXL","default","empty","fill","fixed","height","spacing","width","L","M","S","XL","XS","XXL","XXS","XXXL","L","M","S","XL","XS","XXL","XXS","XXXL"],"q":[[0,"composable"],[54,"composable::dependencies"],[96,"composable::derive_macros"],[102,"composable::effects"],[134,"composable::views"],[341,"composable::views::Event"],[343,"composable::views::Gesture"],[346,"composable::views::gesture"],[402,"composable::views::gpu"],[417,"composable::views::svg"],[432,"composable::views::text"],[548,"composable::views::ui"],[555,"composable::views::ui::accessibility"],[578,"composable::views::ui::colors"],[591,"composable::views::ui::colors::gray"],[594,"composable::views::ui::font"],[616,"composable::views::ui::font::body"],[640,"composable::views::ui::font::label"],[664,"composable::views::ui::font::title"],[688,"composable::views::ui::spacer"],[703,"composable::views::ui::spacer::spacing"],[711,"composable::views::ui::spacing"],[719,"composable::store::testing::clock"],[720,"core::time"],[721,"composable::store::testing"],[722,"composable::reducer"],[723,"composable::effects::task"],[724,"core::default"],[725,"composable::store"],[726,"core::convert"],[727,"core::ops::function"],[728,"core::marker"],[729,"core::clone"],[730,"core::fmt"],[731,"core::cmp"],[732,"core::result"],[733,"core::any"],[734,"composable::dependencies::values"],[735,"core::option"],[736,"core::slice::iter"],[737,"std::time"],[738,"core::future::future"],[739,"futures_core::stream"],[740,"composable::views::output"],[741,"lyon_path::math"],[742,"composable::views::shapes"],[743,"composable::views::layout::spacing"],[744,"composable::views::modifiers::fixed"],[745,"composable::views::modifiers::padding"],[746,"composable::views::gesture::recognizer"],[747,"composable::views::output::gpu"],[748,"alloc::vec"],[749,"composable::views::output::svg"],[750,"alloc::string"],[751,"rustybuzz::hb::common"],[752,"composable::views::text::font"],[753,"rustybuzz::hb::buffer"],[754,"ttf_parser"],[755,"core::hash"],[756,"rustybuzz::hb::face"],[757,"rustybuzz"],[758,"composable::views::ui::font::typography::label"],[759,"composable::views::ui::font::typography::body"],[760,"composable::views::ui::font::typography::title"],[761,"derive_more"],[762,"derive_reducers"],[763,"composable::views::ui::font::typography"]],"i":[7,0,0,34,7,0,0,0,0,0,34,2,6,34,6,10,34,6,10,8,6,10,0,0,8,6,0,34,6,10,34,6,10,6,10,6,10,6,7,6,10,34,6,10,34,6,10,34,6,10,0,6,6,10,0,0,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,0,0,22,30,0,0,0,0,30,35,31,0,0,34,0,0,34,31,31,33,33,33,33,33,31,34,31,33,35,33,35,35,33,35,35,33,31,33,33,33,33,47,0,0,0,0,47,0,0,0,0,0,46,47,0,0,0,0,0,0,46,46,0,0,0,0,0,0,0,39,40,42,52,53,54,55,56,57,48,49,58,59,46,47,52,53,54,55,56,57,48,49,58,59,46,47,101,40,46,47,46,47,46,46,47,47,42,48,42,40,50,39,52,53,54,55,56,57,48,49,58,59,52,53,54,55,56,39,52,50,50,52,50,50,39,52,53,54,55,56,57,48,49,58,59,46,46,46,46,47,0,0,40,52,39,63,52,53,54,55,56,57,48,49,58,59,46,47,101,40,42,45,45,45,45,45,45,51,51,39,39,39,39,39,39,39,39,39,42,57,58,59,101,57,39,52,53,54,55,56,0,0,46,47,101,52,53,54,55,56,57,48,49,58,59,46,47,47,52,53,54,55,56,57,48,49,58,59,46,47,52,53,54,55,56,57,48,49,58,59,46,47,0,52,39,63,60,60,102,102,103,104,105,64,64,64,64,64,0,0,0,64,64,0,66,64,65,66,64,65,66,64,65,66,64,65,66,64,64,65,65,66,66,66,64,65,66,64,66,64,65,66,66,64,65,66,0,64,65,66,64,65,66,64,65,66,64,65,66,0,69,69,69,69,69,69,69,69,69,69,69,69,69,69,0,72,72,72,72,72,72,72,72,72,72,72,72,72,72,79,0,0,0,0,79,0,79,79,0,79,74,75,76,75,78,79,74,80,76,75,78,79,74,80,75,76,78,79,74,80,78,79,74,80,78,79,79,74,80,80,80,79,75,78,79,74,80,75,78,76,79,74,80,76,75,75,78,79,74,80,75,80,79,74,80,75,76,76,79,74,80,75,75,76,75,78,79,74,80,76,78,76,75,80,78,76,75,78,75,80,75,78,79,74,80,76,75,78,79,74,80,76,75,78,79,74,80,76,75,78,79,74,80,75,78,0,0,0,0,0,0,0,90,90,90,0,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,92,92,92,92,92,92,92,92,92,92,92,92,92,92,0,0,92,92,92,0,0,0,0,97,93,95,97,93,95,97,93,95,97,93,95,97,93,95,97,93,95,97,93,95,0,0,0,98,94,91,98,94,91,98,94,91,98,94,91,98,94,91,98,94,91,98,94,91,0,0,0,96,100,99,96,100,99,96,100,99,96,100,99,96,100,99,96,100,99,96,100,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"f":"```````````{{{f{bd}}h}j}{{{f{b{l{c}}}}h}jn}{{{f{c}}}{{f{e}}}{}{}}00{{{f{bc}}}{{f{be}}}{}{}}00{A`j}{{}{{l{c}}}{Abn}}{{}{{Ad{c}}}{Abn}}``2{{{f{b{l{c}}}}}jn}`{cc{}}00{ce{}{}}00{{{l{c}}}{}{Afn}}{{{Ad{c}}}{}n}{e{{l{c}}}n{{Aj{}{{Ah{c}}}}}}{e{{Ad{c}}}n{{Aj{}{{Ah{c}}}}Al}}{{{f{b{l{c}}}}e}j{AnB`Bbn}{{Aj{{f{bc}}}}}}{{{f{b{n{}{{Bd{c}}{Ah{e}}}}}}cg}j{}{}{{Bf{c}}}}1{{{f{{Ad{c}}}}e}jnAf}{c{{Bh{e}}}{}{}}00000{{{f{c}}}Bj{}}00`;{c{{l{c}}}n}{c{{Ad{c}}}{Aln}}``{{{f{{Bl{c}}}}{Bn{e}}}{{Bn{e}}}{}{}}{{{f{{Bl{c}}}}g}{{Bn{e}}}{}{}{{Aj{{f{c}}}{{Ah{{Bn{e}}}}}}}}{{{f{{Bl{c}}}}}{{Bn{{f{c}}}}}{}}{{{f{{Bl{c}}}}}{{f{c}}}C`}{{{f{{Bl{c}}}}}{{f{{Cb{c}}}}}{}}{{{f{c}}}{{f{e}}}{}{}}2{{{f{bc}}}{{f{be}}}{}{}}{{{f{{Bl{c}}}}}{{Bn{c}}}An}{{{f{{Bl{c}}}}}{{Bn{c}}}Cd}{{}{{Bl{c}}}{}}{{{f{{Bl{c}}}}}{{f{e}}}C`{}}{{{f{{Bl{c}}}}{f{Cf}}}{{f{c}}}{}}{{{f{{Bl{c}}}}e}{{Bn{{f{c}}}}}{}{{Aj{{f{c}}}{{Ah{Ch}}}}}}{cc{}}{{{f{{Bl{c}}}}e}{{Bn{{f{c}}}}}{}{{Aj{{f{c}}}}}}{ce{}{}}{{{f{{Bl{c}}}}}Ch{}}0{{{f{{Bl{c}}}}e}Ch{}{{Aj{{f{c}}}{{Ah{Ch}}}}}}{{{f{{Bl{c}}}}}{{Cj{c}}}{}}{{{f{{Bl{c}}}}g}{{Bn{e}}}{}{}{{Aj{{f{c}}}{{Ah{e}}}}}}{{{f{{Bl{c}}}}eg}e{}{}{{Aj{{f{c}}}{{Ah{e}}}}}}{{{f{{Bl{c}}}}gi}e{}{}{{Aj{}{{Ah{e}}}}}{{Aj{{f{c}}}{{Ah{e}}}}}}<{{{f{{Bl{c}}}}e}{{Bh{{f{c}}e}}}{}{}}{{{f{{Bl{c}}}}g}{{Bh{{f{c}}e}}}{}{}{{Aj{}{{Ah{e}}}}}}{{{f{{Bl{c}}}}{Bn{c}}}{{Bn{{`{c}}}}}{}}{{{f{{Bl{c}}}}e}{{Bn{{`{c}}}}}{}{{Aj{}{{Ah{{Bn{c}}}}}}}}{{}{{f{c}}}C`}{c{{Bh{e}}}{}{}}0{{{f{c}}}Bj{}}{{{f{{Bl{c}}}}}{{f{c}}}{}}{{{f{{Bl{c}}}}c}{{`{c}}}{}}{{{f{{Bl{c}}}}}{{`{c}}}Ab}{{{f{{Bl{c}}}}e}{{`{c}}}{}{{Aj{}{{Ah{c}}}}}}{{cg}e`{}{{Aj{}{{Ah{e}}}}}}{{cg}e{}{}{{Aj{}{{Ah{e}}}}}}:`````{{{f{b{Cl{}{{Bd{c}}}}}}ce}j{}{{Bf{c}}}}````````{{{f{{Cn{}{{Bd{c}}}}}}hc}A`{}}{{{f{{Cn{}{{Bd{c}}}}}}D`c}A`{}}{{{f{c}}}{{f{e}}}{}{}}{{{f{bc}}}{{f{be}}}{}{}}{{{f{{Db{ce}}}}}{{Db{ce}}}An{}}{{{f{c}}{f{be}}}j{}{}}{{{f{c}}}j{}}{{{f{{Cn{}{{Bd{c}}}}}}c{f{b{Bn{A`}}}}Dd}j{}}{{{f{Dd}}}h}{{{f{{Cn{}{{Bd{c}}}}}}Ddc}A`{}}{cc{}}{{{f{{Df{}{{Bd{c}}}}}}e}j{}{{Dh{}{{Ah{{Bn{c}}}}}}}}{ce{}{}}{{{f{{Df{}{{Bd{c}}}}}}}{{Db{{Df{}{{Bd{c}}}}e}}}{}{}}{{{f{{Df{}{{Bd{c}}}}}}e}j{}{{Af{c}}}}{{{f{{Db{ce}}}}i}jDf{}{}{{Af{g}}}}{{{f{{Df{}{{Bd{c}}}}}}e}j{}{{Dl{}{{Dj{c}}}}}}{{{f{{Df{}{{Bd{c}}}}}}e}A`{}{{Dl{}{{Dj{c}}}}}}{{{f{{Db{ce}}}}g}A`Df{}{{Dl{}{{Dj{e}}}}}};{{{f{c}}}e{}{}}{c{{Bh{e}}}{}{}}0{{{f{c}}}Bj{}}````````````````````````````{Dn{{`{Dn}}}}{{{f{E`}}}Eb}{{{f{bEd}}EbEb{Eh{Ef}}{f{Ej}}}j}{{{f{c}}}{{f{e}}}{}{}}00000000000{{{f{bc}}}{{f{be}}}{}{}}00000000000`3{{{f{El}}}El}{{{f{En}}}En}{{{f{c}}{f{be}}}j{}{}}0{{{f{c}}}j{}}000{{{f{bEd}}}j}{F`Fb}{{{f{bEd}}EbEbEbEbEbEb}j}:{{{f{Fd}}EbEbEbEb{f{Ej}}{f{bc}}}jEd}{{{f{Dn}}Ff{f{bc}}}jEd}{{{f{Fh}}Ff{f{bc}}}jEd}{{{f{{Fj{c}}}}Ff{f{be}}}jDnEd}{{{f{{Fl{c}}}}Ff{f{be}}}jDnEd}{{{f{{Fn{c}}}}Ff{f{be}}}jDnEd}{{{f{{G`{c}}}}Ff{f{be}}}jDnEd}{{{f{Gb}}EbEbEbEb{f{Ej}}{f{bc}}}jEd}{{{f{F`}}EbEbEbEb{f{Ej}}{f{bc}}}jEd}{{{f{Fb}}EbEbEbEb{f{Ej}}{f{bc}}}jEd}{{{f{Gd}}EbEbEbEb{f{Ej}}{f{bc}}}jEd}{{{f{Gf}}EbEbEbEb{f{Ej}}{f{bc}}}jEd}{{}Fh}{{{f{{Fj{c}}}}ElGhFf}jDn}{{{f{{Fl{c}}}}ElGhFf}jDn}{{{f{{Fn{c}}}}ElGhFf}jDn}{{{f{{G`{c}}}}ElGhFf}jDn}{{{f{Dn}}ElGhFf}j}5{Fd{{`{Fd}}}}0{{EbEb}Fh}{{FdEbEb}{{`{Fd}}}}0{{DnEbEb}{{`{Dn}}}}{cc{}}0000000000{EnEl}{{{Gl{GjGj}}}El}{jEl}3``{{{f{E`}}}Eb}{EbFh}{{DnEb}{{`{Dn}}}}`{ce{}{}}00000000000`3{{{f{bEd}}EbEb}j}````````{{DnEbEbEbEb}{{G`{Dn}}}}{{DnEb}{{G`{Dn}}}}{{DnEbEb}{{G`{Dn}}}}111111{{{f{bEd}}EbEbEbEb}j}````{{GbEbEb}F`}{{{f{Dn}}}Gn}{{{f{Fh}}}Gn}{{{f{{Fj{c}}}}}GnDn}{{{f{{Fl{c}}}}}GnDn}{{{f{{Fn{c}}}}}GnDn}{{{f{{G`{c}}}}}GnDn}``{{{f{c}}}e{}{}}0`{c{{Bh{e}}}{}{}}00000000000{El{{Bh{Enc}}}{}}111111111111{{{f{c}}}Bj{}}00000000000`{EbFh}{{DnEb}{{`{Dn}}}}````````````````````{{{f{c}}}{{f{e}}}{}{}}00{{{f{bc}}}{{f{be}}}{}{}}00{{{f{H`}}}H`}{{{f{Hb}}}Hb}{{{f{Hd}}}Hd}{{{f{c}}{f{be}}}j{}{}}00{{{f{c}}}j{}}00000{{}Hd}{{{f{H`}}{f{H`}}}Ch}{{{f{Hb}}{f{Hb}}}Ch}{{{f{Hd}}{f{Hd}}}Ch}{{{f{H`}}{f{bHf}}}Hh}`{cc{}}00`{ce{}{}}00{{HbEnGhFf}{{Bn{H`}}}}{{{f{c}}}e{}{}}00{c{{Bh{e}}}{}{}}00000{{{f{c}}}Bj{}}00`{{{f{bHj}}EbEb{Eh{Ef}}{f{Ej}}}j}{{{f{c}}}{{f{e}}}{}{}}{{{f{bc}}}{{f{be}}}{}{}}{{{f{bHj}}}j}{{{f{bHj}}EbEbEbEbEbEb}j}:9{Hj{{Gl{{Hn{{Gl{HlHl{Eh{Ef}}}}}}{Hn{Gj}}}}}}{{{f{bHj}}EbEb}j}{EbHj}{{{f{bHj}}EbEbEbEb}j}::9`{{{f{bI`}}EbEb{Eh{Ef}}{f{Ej}}}j}87{{{f{bI`}}}j}{{{f{bI`}}EbEbEbEbEbEb}j}{cc{}}{ce{}{}}{I`Ib}{{{f{bI`}}EbEb}j}{{EbEb}I`}{{{f{bI`}}EbEbEbEb}j}{c{{Bh{e}}}{}{}}0{{{f{c}}}Bj{}}```````````{{{f{Id}}}{{f{Cf}}}}{{{f{If}}}Eb}{{{f{c}}}{{f{e}}}{}{}}00000{{{f{bc}}}{{f{be}}}{}{}}000002{IhIj}{{{f{Il}}}Il}{{{f{In}}}In}{{{f{Id}}}Id}{{{f{J`}}}J`}{{{f{c}}{f{be}}}j{}{}}000{{{f{c}}}j{}}00000{{{f{J`}}{f{J`}}}Jb}{{}In};{{IlIn}Il}{{{f{In}}{f{In}}}Ch}{{{f{Id}}{f{Id}}}Ch}{{{f{J`}}{f{J`}}}Ch}{{{f{If}}}{{Bn{Ib}}}}{{Il{f{{Eh{Ef}}}}Gj}Il}{{{f{Ih}}{f{bHf}}}{{Bh{jJd}}}}{{{f{In}}{f{bHf}}}{{Bh{jJd}}}}{{{f{Id}}{f{bHf}}}{{Bh{jJd}}}}{{{f{J`}}{f{bHf}}}{{Bh{jJd}}}}{cc{}}{{{f{{Cb{Ef}}}}}{{Bn{Il}}}}11111{{{f{{Cb{Ef}}}}Gj}{{Bn{Il}}}}{Jf{{Bn{J`}}}}{{{f{Cf}}}{{Bh{In}}}}{{{f{Cf}}}{{Bh{Id}}}}{{{f{Cf}}}{{Bh{J`}}}}<{{{f{Ih}}}{{f{{Cb{Jh}}}}}}{{{f{Ih}}}{{f{{Cb{Jj}}}}}}{{{f{In}}{f{bc}}}jJl}{{{f{Id}}{f{bc}}}jJl}{{{f{J`}}{f{bc}}}jJl}{{{f{If}}}Eb}{{{f{If}}}{{Bn{Ib}}}}{ce{}{}}00000{{{f{Ih}}}Ch}{{IlId}Il}{{{f{Ih}}}Jn}5{{{f{J`}}{f{J`}}}{{Bn{Jb}}}}{{IlJ`}Il}{{{f{Ih}}{f{K`}}Kb}Ib}8{{IlEb}If}8{{{f{J`}}}Jf}{{{f{If}}{Eh{Ef}}{f{Cf}}}E`}{{{f{c}}}e{}{}}000{c{{Bh{e}}}{}{}}00000000000{{{f{c}}}Bj{}}00000={{IlEb}Il}````````````````{{{f{c}}}{{f{e}}}{}{}}{{{f{bc}}}{{f{be}}}{}{}}{{{f{Kd}}}Kd}{{{f{c}}{f{be}}}j{}{}}{{{f{c}}}j{}}0{{}Kd}{cc{}}{ce{}{}}{{{f{Kd}}Eb}Eb}<;;:`{{}{{Eh{Ef}}}}00000000000{Ef{{Eh{Ef}}}}00``:9{{}{{Kh{Kf}}}}{{}{{Kh{Kj}}}}{{}{{Kh{Kl}}}}{{}{{Kh{Kn}}}}{{}{{Kh{L`}}}}{{}{{Kh{Lb}}}}{{}{{Kh{Ld}}}}{{}{{Kh{Lf}}}}{{}{{Kh{Lh}}}}{{{f{{Kh{c}}}}}{{f{e}}}{}{}}>=``{c{{Bh{e}}}{}{}}0{{{f{c}}}Bj{}}{ec{}{{Aj{}{{Ah{c}}}}}}```{{{f{c}}}{{f{e}}}{}{}}00{{{f{bc}}}{{f{be}}}{}{}}00{cc{}}00{ce{}{}}00666666555```333222111000666666555```333222111000666666555{{}Fh}0000000000{{EbEb}Fh}{EbFh}`0````````````````","D":"BCh","p":[[0,"mut"],[10,"TestClock",0,719],[1,"reference"],[5,"Duration",720],[1,"unit"],[5,"TestStore",0,721],[10,"Reducer",0,722],[5,"Task",0,723],[10,"Default",724],[5,"Store",0,725],[10,"Into",726],[17,"Output"],[10,"FnOnce",727],[10,"Send",728],[10,"Clone",729],[10,"Debug",730],[10,"PartialEq",731],[17,"Action"],[10,"Effects",0],[6,"Result",732],[5,"TypeId",733],[5,"Dependency",54,734],[6,"Option",735],[10,"DependencyDefault",54,734],[1,"slice"],[10,"Copy",728],[1,"str"],[1,"bool"],[5,"Iter",736],[10,"RecursiveReducer",96],[10,"Scheduler",102],[5,"Instant",737],[5,"Scoped",102],[6,"Interval",0,102],[10,"Effects",102],[10,"Future",738],[17,"Item"],[10,"Stream",739],[10,"View",134],[5,"Text",134,432],[1,"f32"],[10,"Output",134,740],[1,"u8"],[1,"array"],[8,"Transform",134,741],[6,"Event",134],[6,"Gesture",134],[5,"RoundedRectangle",134,742],[5,"ContinuousRoundedRectangle",134,742],[10,"Path",134,742],[8,"Bounds",134],[5,"Spacer",134,743],[5,"Fixed",134,744],[5,"FixedWidth",134,744],[5,"FixedHeight",134,744],[5,"Padding",134,745],[5,"Rectangle",134,742],[5,"Ellipse",134,742],[5,"Circle",134,742],[8,"Point",134,741],[1,"u32"],[1,"tuple"],[8,"Size",134,741],[6,"Response",346,746],[5,"Id",346],[5,"Values",346],[5,"Formatter",730],[8,"Result",730],[5,"Output",402,747],[1,"i16"],[5,"Vec",748],[5,"Output",417,749],[5,"String",750],[5,"Language",432,751],[5,"Font",432,752],[5,"Glyphs",432],[5,"UnicodeBuffer",753],[5,"FontConfig",432,752],[6,"Direction",432,751],[5,"Script",432,751],[6,"Ordering",731],[5,"Error",730],[5,"Tag",754],[5,"hb_glyph_info_t",753],[5,"GlyphPosition",753],[10,"Hasher",755],[1,"usize"],[5,"hb_font_t",756],[5,"SerializeFlags",757],[6,"Scale",555],[5,"S",640,758],[5,"Inter",594],[5,"M",616,759],[5,"M",640,758],[5,"S",616,759],[5,"L",664,760],[5,"L",616,759],[5,"L",640,758],[5,"S",664,760],[5,"M",664,760],[8,"Offsets",134],[15,"Resize",341],[15,"Began",343],[15,"Moved",343],[15,"Ended",343]],"r":[[2,102],[5,722],[6,725],[7,723],[8,719],[9,721],[54,734],[55,734],[97,761],[99,762],[100,761],[136,742],[137,742],[138,742],[141,744],[142,744],[143,744],[148,740],[149,745],[150,742],[151,741],[152,742],[155,742],[156,742],[157,741],[158,743],[159,432],[160,741],[244,740],[293,740],[352,746],[389,746],[402,747],[417,749],[433,751],[434,752],[435,752],[438,751],[441,751],[548,594],[553,688],[554,594],[595,763],[610,763],[611,763],[616,759],[617,759],[618,759],[640,758],[641,758],[642,758],[664,760],[665,760],[666,760],[711,703],[712,703],[713,703],[714,703],[715,703],[716,703],[717,703],[718,703]],"b":[[239,"impl-From%3CGesture%3E-for-Event"],[240,"impl-From%3C(u32,+u32)%3E-for-Event"],[241,"impl-From%3C()%3E-for-Event"],[598,"impl-Default-for-Inter%3C\'static,+S%3E"],[599,"impl-Default-for-Inter%3C\'static,+M%3E"],[600,"impl-Default-for-Inter%3C\'static,+M%3E"],[601,"impl-Default-for-Inter%3C\'static,+S%3E"],[602,"impl-Default-for-Inter%3C\'static,+L%3E"],[603,"impl-Default-for-Inter%3C\'static,+L%3E"],[604,"impl-Default-for-Inter%3C\'static,+L%3E"],[605,"impl-Default-for-Inter%3C\'static,+S%3E"],[606,"impl-Default-for-Inter%3C\'static,+M%3E"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAALMBQwAMAAcAFQAAABoAAAAqAAgAPAAAAD4AAgBDAAEAVwACAGIAAABlAAAAcQAEAHcAAAB+AAAAgQAAAIMABACJAAMAjgACAJIAAQCWAAEAmQAEAJ8AAACmABgAwAAHAMkAAADMAAAAzgAOAN4ABQDwAAIA9AAAAPcAAQAGAQAACQEHABsBBAAhAQQAKAEnAFEBAQBUAQ0AYwEbAIIBAACGARIAnAEAAJ4BCQCrAQAArQEDALMBAQC+AQsAzAEPAN0BAwDiAQQA8AECAPYBAgACAgAABQIBAA0CFQAkAgMAKQICADUCBgA/AgMARAILAFUCCwBlAgIAbAIFAHgCCACEAgUAkAIIAJwCBQCoAhcA"}]\ +]')); +if (typeof exports !== 'undefined') exports.searchIndex = searchIndex; +else if (window.initSearch) window.initSearch(searchIndex); diff --git a/search.desc/composable/composable-desc-0-.js b/search.desc/composable/composable-desc-0-.js new file mode 100644 index 00000000..76ede219 --- /dev/null +++ b/search.desc/composable/composable-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("composable", 0, "A Composable Architecture\nAll of the possible actions that can be used to modify …\nEffects are used within Reducers to propagate Actions as …\nWhen a Scheduler uses a repeating interval, that interval …\nThe first Action should be sent immediately.\nBoth unit tests and command line applications often need …\nReducers are responsible for updating a Store’s state in …\nThe state container for the application.\nAsynchronous work being performed by a Store.\nWhen testing, it is important to have control over the …\nA state container for the application testing.\nThe first Action should not be send until after the …\nCancels the task; meaning its Future won’t be polled …\nCreates a new Store with a default initial state.\nErgonomic dependency handling.\nDerive macros used to ease the creation of recursive …\nDetaches the task; leaving its Future running in the …\nAdditional work to be done after performing an action.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nConsumes the Store and returns its current state value.\nStops the Store’s runtime and returns its current state …\nCreates a new Store with its initial state generated by a …\nCreates a new Store with its initial state generated by a …\nChecks that the Store’s Reducer was called with action …\nUpdates the Reducer’s state in response to the action …\nCalls the Store’s Reducer with action and asserts the …\nCalls the Store’s Reducer with action.\nOptional view feature.\nWaits until all scheduled tasks have completed.\nCreates a new Store with state as its initial state.\nCreates a new Store with state as its initial state.\nA wrapper type for accessing dependencies\nThe default value for a dependency.\nReturns None if the dependency is None, otherwise returns …\nReturns None if the dependency is None, otherwise calls f …\nConverts into a Option<&T>.\nReturns a slice of the dependency value, if any. If this …\nMaps the dependency to an Option<T> by cloning the …\nMaps the dependency to an Option<T> by copying the …\nReturns the dependency Some value.\nReturns None if the dependency is None, otherwise calls …\nReturns the argument unchanged.\nCalls the provided closure with a reference to the …\nCalls U::from(self).\nReturns true if the dependency is a None value.\nReturns true if the dependency is a Some value.\nReturns true if the dependency is a Some and the value …\nReturns an iterator over the dependency value, if any.\nMaps to Option<U> by applying a function to a dependency …\nReturns the provided default result (if None), or applies …\nComputes a default function result (if None), or applies a …\nCreates a optional reference to the dependency of type T.\nTransforms into a Result<&T, E>, mapping Some to Ok and …\nTransforms into a Result<&T, E>, mapping Some to Ok and …\nReturns the dependency if it is Some, otherwise returns rhs…\nReturns the dependency if it is Some, otherwise calls f …\nSAFETY\nReturns the contained Some value.\nReturns the dependency Some value or a provided default.\nReturns the dependency Some value or a default.\nReturns the dependency Some value or computes it from a …\nSupply a tuple of dependencies for the supplied closure\nSupply a single dependency for the supplied closure.\nReturns Some if only one of\nAll of the possible actions that can be used to modify …\nSee the RecursiveReducer macro for example usage.\nCompiler Errors\nThis reduce should perform any actions that are needed …\nThe Action type sent by this Effects.\nThe Action sends scheduled by this Scheduler.\nEffects are used within Reducers to propagate Actions as …\nWhen a Scheduler uses a repeating interval, that interval …\nThe first Action should be sent immediately.\nEffects are also Schedulers — able to apply modifiers to …\nAn Effects that scopes its Actions to one that sends child …\nThe first Action should not be send until after the …\nSends the Action after duration.\nSends the Action at instant.\nAn effect that coalesces repeated attempts to send Actions …\nSends the Action every interval.\nReturns the argument unchanged.\nAn effect that runs a Future and, if it returns an Action, …\nCalls U::from(self).\nScopes the Effects down to one that sends child actions.\nAn effect that immediately sends an Action through the …\nAn effect that runs a Stream and sends every Action it …\nA Task represents asynchronous work that will then send …\nAn effect that sends an Action through the Store’s …\nAlias for euclid::default::Box2D<f32>\nView events.\ntouches… buttons…\nAlias for euclid::default::SideOffsets2D<f32>\nA surface, or file format, that views may be rendered to.\nAlias for euclid::default::Point2D<f32>.\nAlias for euclid::default::Size2D<f32>.\nText data\nAlias for euclid::default::Transform2D<f32>\nUser interface element and modifiers to re-configure it.\nCauses a tuple of Views to cascade horizontally, rather …\nAscender height of the Text’s font.\nBegins a new path.\nCapital height of the Text’s font.\nCloses the current path.\nAdds a cubic Bézier to the current path.\nDescender height of the Text’s font. Note that this is a …\nHow the View is drawn\nUser-interface Event handling of the View\nSet the size of the View to a fixed value.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nGPU Output for Views\nHeight of the Text’s font.\nThe extent of the element in the U units along the y axis …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nLine gap of the Text’s font.\nAdds a line to the current path.\nAdd padding to all sides of the View\nAdd the same padding to all sides of the View\nAdd different padding to the horizontal and vertical sides …\nAdd padding to the bottom of the View\nAdd padding to the horizontal sides of the View\nAdd padding to the left side of the View\nAdd padding to the right side of the View\nAdd padding to the top of the View\nAdd padding to the vertical sides of the View\nAdds a quadratic Bézier to the current path.\nThe intrinsic size of the View\nSVG Output for Views\nText handling for View construction.\nA minimal, but viable, user interface layer.\nThe extent of the element in the U units along the x axis …\nThe user interface state carried between cycles by the …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns the argument unchanged.\nCalls U::from(self).\nConsumes the Output and returns the constructed …\nCreates an indexed-triangle data Output.\nReturns the argument unchanged.\nCalls U::from(self).\nConsumes the Output and returns the constructed SVG string.\nCreates a Scalable Vector Graphics Output.\nText is set vertically from bottom to top.\nDefines the direction in which text is to be read.\nA buffer that contains the results of the shaping process.\nInitial, unset direction.\nA script language.\nText is set horizontally from left to right.\nText is set horizontally from right to left.\nA text script.\nText is set vertically from top to bottom.\nReturns the language as a string.\nHorizontal face ascender.\nCapital height,\nClears the content of the glyph buffer and returns an empty\nHorizontal face descender,\nFamily name.\nReturns the argument unchanged.\nCreate a Font from the raw font data.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate a Font from a font collection. Returns the font at …\nConverts an ISO 15924 script tag to a corresponding Script.\nFull font name that reflects all family and relevant …\nGet the glyph infos.\nGet the glyph positions.\nHorizontal height,\nUnique font identifier\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if the buffer contains no elements.\nReturns the length of the data of the buffer.\nLine gap,\nConverts the glyph buffer content into a string.\nFont size in points.\nThe final step in building a Font.\nSubfamily name.\nReturns script’s tag.\nReturns a Text in this font.\nShould begin with the syntax “Version N.M” (upper …\nMinimal Font handling.\nUse large sizes. This is the default on mobile platforms.\nUse medium sizes.\nUse small sizes.\nScale defines a predefined scale for scalable content.\nuse extra large sizes.\nuse extra small sizes.\nUse extra extra large sizes.\nUse extra extra small sizes. This is the default on …\nUse extra extra extra large sizes.\nReturns the argument unchanged.\nCalls U::from(self).\nFont scale per Accessibility level\nShades of gray; where\nGray wih a noticable blue tint\nGray with a subtle blue tint\nGray with no tint; pure grays\nThe Inter font\nBody Font styles.\nReturns the argument unchanged.\nCalls U::from(self).\nLabel Font styles.\nTitle Font styles.\nSets the default font for the supplied closure.\nLarge variant\nMedium variant\nSmall variant\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nLarge variant\nMedium variant\nSmall variant\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nLarge variant\nMedium variant\nSmall variant\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nThe amount of space taken up by a spacer::L()\nThe amount of space taken up by a spacer::M()\nThe amount of space taken up by a spacer::S()\nThe amount of space taken up by a spacer::XL()\nThe amount of space taken up by a spacer::XS()\nThe amount of space taken up by a spacer::XXL()\nThe amount of space taken up by a spacer::XXS()\nThe amount of space taken up by a spacer::XXXL()\nThe amount of space taken up by a spacer::L()\nThe amount of space taken up by a spacer::M()\nThe amount of space taken up by a spacer::S()\nThe amount of space taken up by a spacer::XL()\nThe amount of space taken up by a spacer::XS()\nThe amount of space taken up by a spacer::XXL()\nThe amount of space taken up by a spacer::XXS()\nThe amount of space taken up by a spacer::XXXL()") \ No newline at end of file diff --git a/settings.html b/settings.html new file mode 100644 index 00000000..6ad7a3f9 --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 00000000..275609e0 --- /dev/null +++ b/src-files.js @@ -0,0 +1,4 @@ +var srcIndex = new Map(JSON.parse('[\ +["composable",["",[["dependencies",[],["guard.rs","mod.rs","refs.rs","values.rs"]],["derive_macros",[],["mod.rs"]],["effects",[],["delay.rs","mod.rs","scheduler.rs","task.rs"]],["reducer",[],["mod.rs"]],["store",[["testing",[],["clock.rs","mod.rs"]]],["channel.rs","mod.rs","runtime.rs"]],["views",[["gesture",[],["mod.rs","recognizer.rs","tap.rs"]],["layout",[],["mod.rs","spacing.rs"]],["modifiers",[],["fixed.rs","mod.rs","offset.rs","padding.rs"]],["output",[],["gpu.rs","mod.rs","svg.rs"]],["shapes",[],["mod.rs","rounded.rs"]],["text",[],["font.rs","mod.rs"]],["ui",[["colors",[],["gray.rs","mod.rs","theme.rs"]],["font",[["typography",[],["mod.rs","scale.rs"]]],["mod.rs"]]],["accessibility.rs","mod.rs","spacer.rs"]]],["mod.rs"]]],["lib.rs"]]]\ +]')); +createSrcSidebar(); diff --git a/src/composable/dependencies/guard.rs.html b/src/composable/dependencies/guard.rs.html new file mode 100644 index 00000000..46bbb965 --- /dev/null +++ b/src/composable/dependencies/guard.rs.html @@ -0,0 +1,143 @@ +guard.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+
#![allow(unused_imports)]
+
+use std::any::{Any, TypeId};
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::marker::PhantomData;
+use std::rc::Rc;
+
+pub struct Guard<T: 'static> {
+    _marker: PhantomData<*const T>, // !Send
+}
+
+thread_local! {
+    static PER_THREAD: RefCell<UnhashMap<TypeId, Vec<Rc<dyn Any + 'static>>>> = Default::default();
+}
+
+impl<T: 'static> Guard<T> {
+    pub(crate) fn new(value: T) -> Self {
+        PER_THREAD.with_borrow_mut(|map| {
+            map.entry(TypeId::of::<T>())
+                .or_default()
+                .push(Rc::new(value))
+        });
+
+        Self {
+            _marker: PhantomData,
+        }
+    }
+
+    pub(crate) fn get() -> Option<Rc<T>> {
+        PER_THREAD.with_borrow(|map| {
+            map.get(&TypeId::of::<T>())
+                .and_then(|vec| vec.last())
+                .and_then(|ptr| Rc::clone(ptr).downcast().ok())
+        })
+    }
+}
+
+impl<T: 'static> Drop for Guard<T> {
+    fn drop(&mut self) {
+        // There is no need to handle Guards being used in anything other than a strictly stack-like
+        // manner as they are a private implementation-detail and are only used that way internally.
+        PER_THREAD.with_borrow_mut(|map| map.get_mut(&TypeId::of::<T>()).and_then(|vec| vec.pop()));
+    }
+}
+
+/// `TypeId`s are already hashed.
+pub type UnhashMap<K, V> = HashMap<K, V, BuildHasherDefault<Unhasher>>;
+use std::hash::{BuildHasherDefault, Hasher};
+
+#[derive(Default)]
+pub struct Unhasher {
+    value: u64,
+}
+
+// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_data_structures/unhash/index.html
+impl Hasher for Unhasher {
+    fn finish(&self) -> u64 {
+        self.value
+    }
+
+    // hashing a `TypeId` just calls `write_u64` with the bottom 64-bits
+    fn write(&mut self, _bytes: &[u8]) {
+        unimplemented!();
+    }
+
+    fn write_u64(&mut self, value: u64) {
+        debug_assert_eq!(0, self.value);
+        self.value = value;
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/dependencies/mod.rs.html b/src/composable/dependencies/mod.rs.html new file mode 100644 index 00000000..350bfcbf --- /dev/null +++ b/src/composable/dependencies/mod.rs.html @@ -0,0 +1,155 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+
#![doc = include_str!("README.md")]
+
+pub use values::{Dependency, DependencyDefault};
+
+pub(crate) mod guard;
+mod refs;
+mod values;
+
+/// Supply a tuple of dependencies for the supplied closure
+///
+/// For a single value [`with_dependency`] may be used instead.
+pub fn with_dependencies<T: Tuple, F: FnOnce() -> R, R>(with: T, f: F) -> R {
+    let _guards = with.guards();
+    f()
+}
+
+/// Supply a single dependency for the supplied closure.
+///
+/// A convenience function that just forwards to [`with_dependencies`].
+pub fn with_dependency<T: 'static, F: FnOnce() -> R, R>(with: T, f: F) -> R {
+    with_dependencies((with,), f)
+}
+
+#[doc(hidden)]
+/// A [`tuple`] of up to twenty-five values.
+///
+/// Used by [`with_dependencies`] to set the current [`Dependency`] values for its closure.
+pub trait Tuple {
+    #[doc(hidden)]
+    type Output;
+
+    #[doc(hidden)]
+    fn guards(self) -> Self::Output;
+}
+
+macro_rules! tuple_impl {
+    ( $($val:ident)+ ) => {
+        #[doc(hidden)]
+        #[allow(dead_code)]
+        #[allow(non_snake_case)]
+        impl<$($val: 'static),+> Tuple for ( $($val,)+ ) {
+            type Output = ( $(guard::Guard<$val>,)+ );
+
+            fn guards(self) -> Self::Output {
+                let ( $($val,)+ ) = self;
+                ( $(guard::Guard::new($val),)+ )
+            }
+        }
+    };
+}
+
+tuple_impl! { A }
+tuple_impl! { A B }
+tuple_impl! { A B C }
+tuple_impl! { A B C D }
+tuple_impl! { A B C D E }
+tuple_impl! { A B C D E F }
+tuple_impl! { A B C D E F G }
+tuple_impl! { A B C D E F G H }
+tuple_impl! { A B C D E F G H I }
+tuple_impl! { A B C D E F G H I J }
+tuple_impl! { A B C D E F G H I J K }
+tuple_impl! { A B C D E F G H I J K L }
+tuple_impl! { A B C D E F G H I J K L M }
+tuple_impl! { A B C D E F G H I J K L M N }
+tuple_impl! { A B C D E F G H I J K L M N O }
+tuple_impl! { A B C D E F G H I J K L M N O P }
+tuple_impl! { A B C D E F G H I J K L M N O P Q }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V W }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V W X }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V W X Y }
+// up to 25 dependencies are supported
+
\ No newline at end of file diff --git a/src/composable/dependencies/refs.rs.html b/src/composable/dependencies/refs.rs.html new file mode 100644 index 00000000..3525b5b4 --- /dev/null +++ b/src/composable/dependencies/refs.rs.html @@ -0,0 +1,83 @@ +refs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
use std::borrow::Borrow;
+use std::ops::Deref;
+
+/// Used to return a reference to a dependency or a separate owned value.
+///
+/// Used by:
+/// - [`unwrap_or`][`super::Dependency::unwrap_or`]
+/// - [`unwrap_or_else`][`super::Dependency::unwrap_or_else`]
+/// - [`unwrap_or_default`][`super::Dependency::unwrap_or_default`]
+/// - [`or`][`super::Dependency::or`]
+/// - [`or_else`][`super::Dependency::or_else`]
+/// - [`xor`][`super::Dependency::xor`]
+pub enum Ref<'a, T: 'a> {
+    /// a reference of type T
+    Borrowed(&'a T),
+    /// a value of type T
+    Owned(T),
+}
+
+impl<T> Deref for Ref<'_, T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        match self {
+            Ref::Borrowed(reference) => reference,
+            Ref::Owned(value) => value,
+        }
+    }
+}
+
+impl<T> AsRef<T> for Ref<'_, T> {
+    fn as_ref(&self) -> &T {
+        self.deref()
+    }
+}
+
+impl<T> Borrow<T> for Ref<'_, T> {
+    fn borrow(&self) -> &T {
+        self.deref()
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/dependencies/values.rs.html b/src/composable/dependencies/values.rs.html new file mode 100644 index 00000000..c8fd336c --- /dev/null +++ b/src/composable/dependencies/values.rs.html @@ -0,0 +1,687 @@ +values.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+
use std::borrow::Borrow;
+use std::cell::{Cell, OnceCell};
+use std::ops::Deref;
+use std::rc::Rc;
+
+use super::{guard::Guard, refs::Ref};
+
+/// A wrapper type for accessing dependencies
+pub struct Dependency<T: 'static> {
+    inner: OnceCell<Rc<T>>,
+}
+
+impl<T> Default for Dependency<T> {
+    fn default() -> Self {
+        let cell = OnceCell::new();
+
+        if let Some(inner) = Guard::get() {
+            cell.set(inner).ok();
+        }
+
+        Self { inner: cell }
+    }
+}
+
+/// - The methods of `Dependency` are very similar to those of [`std::option::Option`], as
+///   dependencies are *optionally* present.
+/// - However, a `Dependency` on a type with a [`DependencyDefault`] also implements the
+///   [`AsRef`], [`Deref`] and [`Borrow`] traits. Event if a value has not been explicitly
+///   registered for it, the `Dependency` will still be able to [`as_ref`], [`deref`] and
+///   [`borrow`] this default value.
+///
+///  [`std::option::Option`]: std::option
+///  [`as_ref`]: Dependency::as_ref
+///  [`deref`]: Dependency::deref
+///  [`borrow`]: Dependency::borrow
+impl<T> Dependency<T> {
+    /// Creates a optional reference to the dependency of type `T`.
+    #[inline]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    /// Returns `true` if the dependency is a [`Some`] value.
+    #[inline(always)]
+    pub fn is_some(&self) -> bool {
+        self.inner.get().is_some()
+    }
+
+    /// Returns `true` if the dependency is a [`Some`] and the value inside of it matches a predicate.
+    #[inline(always)]
+    pub fn is_some_and(&self, f: impl FnOnce(&T) -> bool) -> bool {
+        self.as_deref().filter(|inner| f(*inner)).is_some()
+    }
+
+    /// Returns `true` if the dependency is a [`None`] value.
+    #[inline(always)]
+    pub fn is_none(&self) -> bool {
+        self.inner.get().is_none()
+    }
+
+    /// Returns a slice of the dependency value, if any. If this is [`None`], an empty slice is returned.
+    #[inline(always)]
+    pub fn as_slice(&self) -> &[T] {
+        self.as_deref().map_or(&[], std::slice::from_ref)
+    }
+
+    /// Returns an iterator over the dependency value, if any.
+    #[inline(always)]
+    pub fn iter(&self) -> std::slice::Iter<'_, T> {
+        self.as_slice().iter()
+    }
+
+    /// Returns the dependency [`Some`] value.
+    ///
+    /// # Panics
+    /// Panics if the dependency is a [`None`] with a custom panic message provided by `msg`.
+    #[inline(always)]
+    pub fn expect(&self, msg: &str) -> &T {
+        self.as_deref().expect(msg)
+    }
+
+    /// Returns the contained [`Some`] value.
+    ///
+    /// # Panics
+    /// Panics if the dependency value equals [`None`].
+    #[inline(always)]
+    pub fn unwrap(&self) -> &T {
+        self.as_deref().unwrap()
+    }
+
+    /// Returns the dependency [`Some`] value or a provided default.
+    #[inline(always)]
+    pub fn unwrap_or(&self, default: T) -> Ref<'_, T> {
+        self.as_deref()
+            .map(Ref::Borrowed)
+            .unwrap_or(Ref::Owned(default))
+    }
+
+    /// Returns the dependency [`Some`] value or computes it from a closure.
+    #[inline]
+    pub fn unwrap_or_else<F>(&self, f: F) -> Ref<'_, T>
+    where
+        F: FnOnce() -> T,
+    {
+        self.as_deref()
+            .map(Ref::Borrowed)
+            .unwrap_or_else(|| Ref::Owned(f()))
+    }
+
+    /// Returns the dependency [`Some`] value or a default.
+    #[inline(always)]
+    pub fn unwrap_or_default(&self) -> Ref<'_, T>
+    where
+        T: Default,
+    {
+        self.as_deref()
+            .map(Ref::Borrowed)
+            .unwrap_or_else(|| Ref::Owned(T::default()))
+    }
+
+    /// Maps to [`Option<U>`] by applying a function to a dependency value (if [`Some`])
+    /// or returns [`None`] (if [`None`]).
+    #[inline]
+    pub fn map<U, F>(&self, f: F) -> Option<U>
+    where
+        F: FnOnce(&T) -> U,
+    {
+        self.as_deref().map(f)
+    }
+
+    /// Calls the provided closure with a reference to the dependency value (if [`Some`]).
+    #[inline]
+    pub fn inspect<F>(&self, f: F) -> Option<&T>
+    where
+        F: FnOnce(&T),
+    {
+        self.as_deref().inspect(|inner| f(*inner))
+    }
+
+    /// Returns the provided default result (if [`None`]),
+    /// or applies a function to the dependency value (if [`Some`]).
+    #[inline]
+    pub fn map_or<U, F>(&self, default: U, f: F) -> U
+    where
+        F: FnOnce(&T) -> U,
+    {
+        self.as_deref().map_or(default, f)
+    }
+
+    /// Computes a default function result (if [`None`]), or
+    /// applies a different function to the dependency value (if [`Some`]).
+    #[inline]
+    pub fn map_or_else<U, D, F>(&self, default: D, f: F) -> U
+    where
+        D: FnOnce() -> U,
+        F: FnOnce(&T) -> U,
+    {
+        self.as_deref().map_or_else(default, f)
+    }
+
+    /// Transforms into a [`Result<&T, E>`], mapping [`Some`] to
+    /// [`Ok`] and [`None`] to [`Err`].
+    #[inline(always)]
+    pub fn ok_or<E>(&self, err: E) -> Result<&T, E> {
+        self.as_deref().ok_or(err)
+    }
+
+    /// Transforms into a [`Result<&T, E>`], mapping [`Some`] to
+    /// [`Ok`] and [`None`] to [`Err`].
+    #[inline(always)]
+    pub fn ok_or_else<E, F>(&self, err: F) -> Result<&T, E>
+    where
+        F: FnOnce() -> E,
+    {
+        self.as_deref().ok_or_else(err)
+    }
+
+    /// Converts into a [`Option<&T>`].
+    ///
+    /// # Note
+    /// This is the preferred method for producing an [`Option`] to use with the
+    /// [question mark operator][`?`].[^try]
+    ///
+    /// [`?`]: https://doc.rust-lang.org/nightly/core/option/index.html#the-question-mark-operator-
+    /// [^try]: Once the [Try trait](https://github.com/rust-lang/rust/issues/84277) is stabilized
+    ///         it will be implemented for `Dependency`.
+    #[inline]
+    pub fn as_deref(&self) -> Option<&T> {
+        self.inner.get().map(|inner| inner.deref())
+    }
+
+    /// Returns [`None`] if the dependency is [`None`], otherwise returns `rhs`.
+    #[inline(always)]
+    pub fn and<U>(&self, rhs: Option<U>) -> Option<U> {
+        self.as_deref().and(rhs)
+    }
+
+    /// Returns [`None`] if the dependency is [`None`], otherwise calls `f` with the
+    /// dependency value and returns the result.
+    #[inline]
+    pub fn and_then<U, F: FnOnce(&T) -> Option<U>>(&self, f: F) -> Option<U> {
+        self.as_deref().and_then(f)
+    }
+
+    /// Returns [`None`] if the dependency is [`None`], otherwise calls `predicate`
+    /// with the dependency value and returns:
+    #[inline]
+    pub fn filter<P>(&self, predicate: P) -> Option<&T>
+    where
+        P: FnOnce(&T) -> bool,
+    {
+        self.as_deref().filter(|inner| predicate(*inner))
+    }
+
+    /// Returns the dependency if it is [`Some`], otherwise returns `rhs`.
+    #[inline(always)]
+    pub fn or(&self, rhs: Option<T>) -> Option<Ref<'_, T>> {
+        self.as_deref().map(Ref::Borrowed).or(rhs.map(Ref::Owned))
+    }
+
+    /// Returns the dependency if it is [`Some`], otherwise calls `f` and returns the result.
+    #[inline]
+    pub fn or_else<F>(&self, f: F) -> Option<Ref<'_, T>>
+    where
+        F: FnOnce() -> Option<T>,
+    {
+        self.as_deref()
+            .map(Ref::Borrowed)
+            .or_else(|| f().map(Ref::Owned))
+    }
+
+    /// Returns [`Some`] if only one of
+    /// - the dependency, or
+    /// - `rhs`
+    ///
+    /// is [`Some`], otherwise returns [`None`].
+    #[inline(always)]
+    pub fn xor(&self, rhs: Option<T>) -> Option<Ref<'_, T>> {
+        self.as_deref().map(Ref::Borrowed).xor(rhs.map(Ref::Owned))
+    }
+
+    /// Maps the dependency to an [`Option<T>`] by **copying** the contents of the option.
+    #[inline(always)]
+    pub fn copied(&self) -> Option<T>
+    where
+        T: Copy,
+    {
+        self.as_deref().copied()
+    }
+
+    /// Maps the dependency to an [`Option<T>`] by **cloning** the contents of the option.
+    #[inline(always)]
+    pub fn cloned(&self) -> Option<T>
+    where
+        T: Clone,
+    {
+        self.as_deref().cloned()
+    }
+}
+
+/// The default value for a dependency.
+///
+/// There may be many different versions of dependencies for testing but there is often just
+/// a single default implementation for use in the the actual application.
+///
+/// Implementing this trait for a type ensures that a [`Dependency`] on it will always have
+/// a value. If the `DependencyDefault` value has not been [overridden][`super::with_dependencies`]
+/// it will be returned.
+///
+/// <div class="warning">
+/// Attempting to use this default behavior in a unit test <em>will fail the test</em>,
+/// as tests are <u>required</u> to explicitly supply all of their dependencies.
+/// </div>
+///
+/// # Note
+/// `DependencyDefault`s are only created as needed. When its first [`Dependency`] is
+///  created, [`default`][`Default::default`] will be called once and the returned value will
+///  be cached.
+pub trait DependencyDefault: Default {}
+
+impl<T: DependencyDefault> Dependency<T> {
+    #[track_caller]
+    #[inline(never)]
+    fn get_or_insert_default(&self) -> &T {
+        self.as_deref().unwrap_or_else(|| {
+            if cfg!(test) {
+                let detailed_explanation = r#".
+
+DependencyDefault types are not allowed to use their default implementation within units tests.
+Either register the dependency on the TestStore or use with_dependency(…) within the test itself.
+"#;
+                panic!(
+                    "Dependency<{0}> was constructed during a test,\nbut {0} was not registered{1}",
+                    std::any::type_name::<T>(),
+                    detailed_explanation
+                );
+            }
+
+            let guard = Guard::new(T::default());
+            std::mem::forget(guard);
+
+            self.inner.set(Guard::get().unwrap()).ok();
+            self.as_deref().unwrap()
+        })
+    }
+
+    /// ## SAFETY
+    /// A `DependencyDefault`, once fetched, will last for the life of the process.
+    ///
+    /// Holding this reference is not advised as it will not reflect further overrides of this dependency.
+    #[inline(always)]
+    pub fn static_ref() -> &'static T {
+        #[allow(unsafe_code)]
+        unsafe {
+            std::mem::transmute(Self::default().get_or_insert_default())
+        }
+    }
+}
+
+impl<T: DependencyDefault> Deref for Dependency<T> {
+    type Target = T;
+
+    #[inline(always)]
+    fn deref(&self) -> &Self::Target {
+        self.get_or_insert_default()
+    }
+}
+
+impl<T: DependencyDefault> AsRef<T> for Dependency<T> {
+    #[inline(always)]
+    fn as_ref(&self) -> &T {
+        self.get_or_insert_default()
+    }
+}
+
+impl<T: DependencyDefault> Borrow<T> for Dependency<T> {
+    #[inline(always)]
+    fn borrow(&self) -> &T {
+        self.get_or_insert_default()
+    }
+}
+
+impl<T: DependencyDefault> DependencyDefault for Cell<T> {}
+
\ No newline at end of file diff --git a/src/composable/derive_macros/mod.rs.html b/src/composable/derive_macros/mod.rs.html new file mode 100644 index 00000000..76712edb --- /dev/null +++ b/src/composable/derive_macros/mod.rs.html @@ -0,0 +1,511 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+
//! Derive macros used to ease the creation of recursive reducers.
+//!
+//! - [`RecursiveReducer`]  
+//!   `#[derive(RecursiveReducer)]` on a `enum` or `struct` that contains other [`Reducer`]
+//!   types will derive a [`Reducer`] implementation for it.
+//! - [`TryInto`]  
+//!   `#[derive(TryInto)]` on a `Action` whose variants contain another [`Reducer`]’s `Action`s
+//!   allows an attempted conversion to…
+//! - [`From`]  
+//!   `#[derive(TryInto)]` on a `Action` whose variants contain another [`Reducer`]’s `Action`s
+//!   allows an attempted conversion from…
+//!
+//! These macros produce efficient implementations of the [`Reducer`], [`std::convert::TryInto`]
+//! and [`std::convert::From`] traits so that they do not have to be implemented manually.
+//!
+//! ##### Automatic Derived Reducers
+//!
+//! Two other types are valid [`Reducer`]s whenever they contain a [`Reducer`].
+//! - [`Option`]  
+//! - [`Box`]  
+//!
+//! These do not require the [`RecursiveReducer`] and [automatically apply][auto].
+//!
+//! [auto]: crate::Reducer#foreign-impls
+//! [`RecursiveReducer`]: derive_reducers::RecursiveReducer
+//! [`Reducer`]: crate::Reducer
+//! [`TryInto`]: #reexports
+//! [`From`]: #reexports
+//!
+//! # Composite Reducers
+//!
+//! A `RecursiveReducer` **`struct`** represents a parent-child relationship between `Reducer`s.
+//! This is the most common use of `RecursiveReducer` in large applications and forms the core
+//! “Composability” of the Composable Architecture.
+//!
+//! The application is broken up into different `mod`ules representing the different Domains or
+//! Features of the application; each with its own `Action`s and `State`.
+//!
+//! These `Reducer`s are then collected into various composite `Reducer`s that contain and
+//! coordinate between them.  
+//!
+//! Each composite `Reducer` is written with the knowledge of its own `Action`s and the `Action`s
+//! of its immediate children. The `Action`s of its parent are unknown to it and (by convention) it
+//! does not traffic in the `Action`s of its grandchildren.
+//!
+//! Deciding which Domains need to be coordinated between, and thus should be siblings under a
+//! parent Domains, is the art of designing the application with an architecture like this one.
+//!
+//! Even though the application `struct` recursively contains the `State`s of all of it Features
+//! it usually does not end up being very “tall.”
+//!
+//! See [Unidirectional Event Architecture][crate] for more.
+//!
+//! ```rust
+//! mod A {
+//! #   use composable::*;
+//!     #[derive(Default)]
+//!     pub struct State { /* … */ }
+//!
+//!     #[derive(Clone)] // ⒈
+//!     pub enum Action { /* … */ }
+//!
+//!     impl Reducer for State {
+//!         type Action = Action;
+//!         type Output = Self;
+//!         
+//!         fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+//!             match action { /* … */ }
+//!         }
+//!     }
+//! }
+//!
+//! mod B {
+//! #   use composable::*;
+//!     #[derive(Default)]
+//!     pub struct State;
+//!
+//!     #[derive(Clone)] // ⒈
+//!     pub enum Action { /* … */ }
+//!
+//!     impl Reducer for State {
+//!         type Action = Action;
+//!         type Output = Self;
+//!
+//!         fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+//!             match action { /* … */ }
+//!         }
+//!     }
+//! }
+//!
+//! # use composable::*;
+//! #[derive(Default, RecursiveReducer)] // ⒉
+//! struct State {
+//!     a: A::State,
+//!     b: B::State,
+//! #
+//! #   #[reducer(skip)]
+//! #   c: Vec<u32>,
+//! }
+//!
+//! #[derive(Clone, From, TryInto)] // ⒊
+//! enum Action {
+//!     SomeAction, // parent actions
+//!     SomeOtherAction,
+//!
+//!     A(A::Action), // ⒋
+//!     B(B::Action),
+//! }
+//!
+//! impl RecursiveReducer for State { // ⒌
+//!     type Action = Action;
+//!
+//!     fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+//!         match action {
+//!             Action::SomeAction => { /* … */ }
+//!             Action::SomeOtherAction => { /* … */ }
+//!
+//!             // in this example, the parent reducer has
+//!             // no explicit handling of any child actions
+//!             _ => {}
+//!         }
+//!     }
+//! }
+//!
+//! # let store = Store::with_initial(State::default());
+//! ```
+//! 1. Now that `Action`s are being passed to multiple `Reducers` they must be `Clone`.
+//! 2. The `RecursiveReducer` derive macro constructs a recursive `Reducer` from the `struct`.
+//! 3. The `From` and `TryInfo` derive macros ensure that conversions work, when they should,
+//!    between parent and child `Action`s. These conversions utilize #4…
+//! 4. The parent has one (and only one) `Action` for the `Action`s of each of its children.
+//! 5. Finally, an implementation of the `RecursiveReducer` trait containing the parent’s `reduce`
+//!    method. `RecursiveReducer::reduce` is run before the `Reducer::reduce` methods of its
+//!    fields. Resulting in:
+//!
+//!    - `self.reduce()`, then
+//!    - `self.a.reduce()`, then
+//!    - `self.b.reduce()`.
+//!
+//! ### Ignoring fields
+//!
+//! Compound `Reducer`s often contain fields other than the child `Reducer`s. After all, it has
+//! its own `Reducer` and that `Reducer` may need its own state.
+//!
+//! The `RecursiveReducer` macro comes with an associated attribute that allows it to skip
+//! `struct` members that should not ne made part of the `Reducer` recursion.
+//!
+//! ```ignore
+//! #[derive(RecursiveReducer)]
+//! struct State {
+//!     a: A::State,
+//!     b: B::State,
+//!
+//!     #[reducer(skip)]
+//!     c: Vec<u32>,
+//! }
+//! ```
+//!
+//! # Alternate Reducers
+//!
+//! A `RecursiveReducer` **`enum`** represents a single state that is best
+//! represented by an enumeration a separate reducers.
+//!
+//! **Alternate `Reducer`s** are less common than **Composite `Reducer`s** so a more concrete example may
+//! help…
+//!
+//! ```
+//! # mod authenticated {
+//! #    #[derive(Clone)]
+//! #    pub enum Action {}
+//! #    pub struct State {}
+//! #
+//! #    use composable::*;
+//! #    impl Reducer for State {
+//! #        type Action = Action;
+//! #        type Output = Self;
+//! #        fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {}
+//! #    }
+//! # }
+//! #
+//! # mod unauthenticated {
+//! #    #[derive(Clone)]
+//! #    pub enum Action {}
+//! #    pub struct State {}
+//! #
+//! #    use composable::*;
+//! #    impl Reducer for State {
+//! #        type Action = Action;
+//! #        type Output = Self;
+//! #        fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {}
+//! #    }
+//! # }
+//! # use composable::*;
+//! #[derive(RecursiveReducer)]
+//! enum State {
+//!     LoggedIn(authenticated::State),
+//!     LoggedOut(unauthenticated::State),
+//! #
+//! #   #[reducer(skip)]
+//! #   Other,
+//! }
+//!
+//! #[derive(Clone, From, TryInto)]
+//! enum Action {
+//!     LoggedIn(authenticated::Action),
+//!     LoggedOut(unauthenticated::Action),
+//! }
+//!
+//! impl RecursiveReducer for State {
+//!     type Action = Action;
+//!
+//!     fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+//!         // logic independent of the user’s authentication
+//!     }
+//! }
+//! ```
+//!
+//! `authenticated::Action`s will only run when the state is `LoggedIn` and vice-versa..
+//!
+//! ---
+//! <br />
+//!
+//! Now, the [automatic derive reducer] behavior of [`Option`] is easy to described.
+//! It behaves is as if it were:
+//!
+//! ```ignore
+//! #[derive(RecursiveReducer)]
+//! enum Option<T: Reducer> {
+//!     #[reducer(skip)]
+//!     None,
+//!     Some(T),
+//! }
+//! ```
+//! Although, currently, the `RecursiveReducer` macro does not work with generic parameters on the
+//! type it is attempting to derive the `Reducer` trait for.
+//!
+//! [automatic derive reducer]: #automatic-derived-reducers
+
+#[doc(no_inline)]
+pub use derive_more::{From, TryInto};
+
+pub use derive_reducers::RecursiveReducer;
+
+use crate::Effects;
+
+/// See the [`RecursiveReducer`][`derive_reducers::RecursiveReducer`] macro for example usage.
+pub trait RecursiveReducer {
+    /// All of the possible actions that can be used to modify state.
+    /// Equivalent to [`Reducer::Action`][`crate::Reducer::Action`].
+    type Action;
+
+    /// This `reduce` should perform any actions that are needed _before_ the macro recurses
+    /// into the other reducers.
+    fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>);
+}
+
\ No newline at end of file diff --git a/src/composable/effects/delay.rs.html b/src/composable/effects/delay.rs.html new file mode 100644 index 00000000..688dd4c6 --- /dev/null +++ b/src/composable/effects/delay.rs.html @@ -0,0 +1,147 @@ +delay.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+
use std::future::Future;
+use std::pin::Pin;
+use std::sync::{Arc, Mutex};
+use std::task::{Context, Poll, Waker};
+use std::time::Instant;
+
+use futures::Stream;
+
+use crate::dependencies::Dependency;
+use crate::effects::scheduler::Scheduler;
+
+pub(crate) enum State {
+    New(Instant),
+    Waiting(Waker),
+    Ready,
+    Done,
+}
+
+pub struct Delay(Arc<Mutex<State>>);
+
+impl Future for Delay {
+    type Output = ();
+
+    #[inline(always)]
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.poll_next(cx).map(|_| ()) // Ready(Some()) → Ready(())
+    }
+}
+
+impl Stream for Delay {
+    type Item = ();
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let mut state = self
+            .0
+            .lock() //
+            .unwrap_or_else(|err| err.into_inner());
+
+        match &mut *state {
+            State::New(instant) => {
+                let instant = *instant;
+                *state = State::Waiting(cx.waker().clone());
+                drop(state);
+
+                // Now that it has a Waker…
+                let scheduler = Dependency::<Scheduler>::new();
+                scheduler.add(instant, self.0.clone());
+
+                Poll::Pending
+            }
+            State::Waiting(waker) => {
+                waker.clone_from(cx.waker()); // update the waker if needed
+                Poll::Pending
+            }
+            State::Ready => {
+                *state = State::Done;
+                Poll::Ready(Some(()))
+            }
+            State::Done => Poll::Ready(None),
+        }
+    }
+
+    #[inline(always)]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (1, Some(1))
+    }
+}
+
+impl Delay {
+    pub fn new(instant: Instant) -> Self {
+        Delay(Arc::new(Mutex::new(State::New(instant))))
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/effects/mod.rs.html b/src/composable/effects/mod.rs.html new file mode 100644 index 00000000..5192ee42 --- /dev/null +++ b/src/composable/effects/mod.rs.html @@ -0,0 +1,637 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+
#![doc = include_str!("README.md")]
+
+use std::cell::RefCell;
+use std::collections::VecDeque;
+use std::iter::from_fn;
+use std::marker::PhantomData as Marker;
+use std::rc::Weak;
+use std::time::{Duration, Instant};
+
+use futures::stream::{iter, once};
+use futures::{Future, Stream, StreamExt};
+
+pub(crate) use delay::Delay;
+pub(crate) use task::Executor;
+#[doc(hidden)]
+pub use task::Task;
+
+mod delay;
+pub(crate) mod scheduler;
+mod task;
+
+/// `Effects` are used within `Reducer`s to propagate `Action`s as side-effects of performing other `Action`s.
+///
+/// `Effects` are also [`Scheduler`]s — able to apply modifiers to when (and how often) `Action`s. are sent.
+///
+/// See [the module level documentation](self) for more.
+pub trait Effects: Clone + Scheduler<Action = <Self as Effects>::Action> {
+    /// The `Action` type sent by this `Effects`.
+    type Action;
+
+    /// An effect that immediately sends an [`Action`][`Self::Action`] through
+    /// the `Store`’s [`Reducer`][`crate::Reducer`].
+    fn send(&self, action: impl Into<<Self as Effects>::Action>);
+
+    /// A [`Task`] represents asynchronous work that will then [`send`][`crate::Store::send`]
+    /// zero or more [`Action`][`Self::Action`]s back into the `Store`’s [`Reducer`][`crate::Reducer`]
+    /// as it runs.
+    ///
+    /// Use this method if you need to ability to [`cancel`][Task::cancel] the task
+    /// while it is running. Otherwise [`future`][Effects::future] or [`stream`][Effects::stream]
+    /// should be preferred.
+    fn task<S: Stream<Item = <Self as Effects>::Action> + 'static>(&self, stream: S) -> Task;
+
+    /// An effect that runs a [`Future`][`std::future`] and, if it returns an
+    /// [`Action`][`Self::Action`], sends it through the `Store`’s [`Reducer`][`crate::Reducer`].
+    #[inline(always)]
+    fn future<F: Future<Output = Option<<Self as Effects>::Action>> + 'static>(&self, future: F)
+    where
+        <Self as Effects>::Action: 'static,
+    {
+        let stream = once(future).filter_map(|action| async move { action });
+        self.task(stream).detach()
+    }
+
+    /// An effect that runs a [`Stream`](https://docs.rs/futures/latest/futures/stream/index.html)
+    /// and sends every [`Action`][`Self::Action`] it returns through the `Store`’s
+    /// [`Reducer`][`crate::Reducer`].
+    #[inline(always)]
+    fn stream<S: Stream<Item = <Self as Effects>::Action> + 'static>(&self, stream: S) {
+        self.task(stream).detach()
+    }
+
+    /// Scopes the `Effects` down to one that sends child actions.
+    ///
+    /// For example, the inner loop of the [`RecursiveReducer`] macro is,
+    /// effectively, just calling
+    ///
+    /// ```rust ignore
+    /// if let Ok(action) = action.clone().try_into() {
+    ///     reduce(&mut self.child_reducer, action, effects.scope());
+    /// }
+    /// ```
+    /// on each child-reducer.
+    ///
+    /// [`RecursiveReducer`]: crate::derive_macros
+    #[inline(always)]
+    fn scope<ChildAction>(&self) -> Scoped<Self, ChildAction>
+    where
+        <Self as Effects>::Action: From<ChildAction>,
+    {
+        Scoped(self.clone(), Marker)
+    }
+}
+
+/// [`Effects`] are also `Scheduler`s — able to apply modifiers to when (and how often) `Action`s. are sent.
+pub trait Scheduler {
+    /// The `Action` sends scheduled by this `Scheduler`.
+    type Action;
+
+    #[doc(hidden)]
+    fn now(&self) -> Instant {
+        Instant::now()
+    }
+
+    #[doc(hidden)]
+    fn schedule(
+        &self,
+        action: Self::Action,
+        after: impl IntoIterator<Item = Delay> + 'static,
+    ) -> Task
+    where
+        Self::Action: Clone + 'static;
+
+    /// Sends the `Action` after `duration`.
+    fn after(&self, duration: Duration, action: Self::Action) -> Task
+    where
+        Self::Action: Clone + 'static,
+    {
+        let instant = self.now() + duration;
+        self.at(instant, action)
+    }
+
+    /// Sends the `Action` at `instant`.
+    fn at(&self, instant: Instant, action: Self::Action) -> Task
+    where
+        Self::Action: Clone + 'static,
+    {
+        let mut task = self.schedule(action.into(), [Delay::new(instant)]);
+        task.when = Some(instant);
+        task
+    }
+
+    /// Sends the `Action` every `interval`.
+    fn every(&self, interval: Interval, action: Self::Action) -> Task
+    where
+        Self::Action: Clone + 'static,
+    {
+        let (mut n, duration) = match interval {
+            Interval::Leading(duration) => (0, duration), // 0 × delay => no initial delay
+            Interval::Trailing(duration) => (1, duration),
+        };
+
+        let start = self.now();
+        self.schedule(
+            action,
+            from_fn(move || {
+                let instant = start.checked_add(duration.checked_mul(n)?)?;
+                n = n.checked_add(1)?;
+
+                Some(Delay::new(instant))
+            }),
+        )
+    }
+
+    /// An effect that coalesces repeated attempts to send [`Action`][`Effects::Action`]s
+    /// through the `Store`’s [`Reducer`][`crate::Reducer`] into a singe send.
+    /// Once `timeout` has elapsed with no further `Action`s being attempted,
+    /// the last `Action` will be sent.
+    ///
+    /// The `debounce` function will automatically update the information
+    /// stored in `previous` as it runs. The `Task` debounced by this call
+    /// will be the _previous_ task for the next call, if any.
+    fn debounce(&self, action: Self::Action, previous: &mut Option<Task>, interval: Interval)
+    where
+        Self::Action: Clone + 'static,
+    {
+        let task = match interval {
+            Interval::Trailing(timeout) => self.after(timeout, action),
+            Interval::Leading(timeout) => {
+                let now = self.now();
+                match previous.as_ref().and_then(|task| task.when).as_ref() {
+                    None => self.at(now, action),
+                    Some(then) => {
+                        if now <= *then + timeout {
+                            return; // A leading debounce DROPS subsequent actions within the interval
+                        }
+
+                        self.at(now, action)
+                    }
+                }
+            }
+        };
+
+        *previous = Some(task);
+    }
+
+    /// An effect that sends an [`Action`][`Effects::Action`] through the `Store`’s
+    /// [`Reducer`][`crate::Reducer`] if at least one `interval` of time has passed
+    /// since `previous` was sent. Otherwise, all subsequent actions but the last
+    /// are dropped until that time; which resets the countdown until the next
+    /// debounced action can be sent.
+    ///
+    /// The `throttle` function will automatically update the information
+    /// stored in `previous` as it runs. The `Task` throttled by this call
+    /// will be the _previous_ task for the next call, if any.
+    fn throttle(&self, action: Self::Action, previous: &mut Option<Task>, interval: Interval)
+    where
+        Self::Action: Clone + 'static,
+    {
+        let now = self.now();
+        let timeout = interval.duration();
+
+        let when = match previous.take().and_then(|task| task.when) {
+            Some(when) if when > now => when, // previous was not yet sent — replace it
+            Some(when) if when + timeout > now => when + timeout, // previous was sent recently
+            _ => match interval {
+                Interval::Leading(_) => now,
+                Interval::Trailing(_) => now + timeout,
+            },
+        };
+
+        let task = self.at(when, action);
+        *previous = Some(task);
+    }
+}
+
+/// When a [`Scheduler`] uses a repeating interval, that interval can begin immediately, a `Leading`
+/// interval, or it may begin after the first delay, a `Trailing` interval.
+pub enum Interval {
+    /// The first `Action` should be sent immediately.
+    Leading(Duration),
+    /// The first `Action` should not be send until after the `Duration` has passed.
+    Trailing(Duration),
+}
+
+impl Interval {
+    pub fn duration(&self) -> Duration {
+        match self {
+            Interval::Leading(duration) => *duration,
+            Interval::Trailing(duration) => *duration,
+        }
+    }
+}
+
+/// An `Effects` that scopes its `Action`s to one that sends child actions.
+///
+/// This `struct` is created by the [`scope`] method on [`Effects`]. See its
+/// documentation for more.
+///
+/// [`scope`]: Effects::scope
+pub struct Scoped<Parent, Child>(Parent, Marker<Child>);
+
+// Using `#[derive(Clone)]` adds a `Clone` requirement to all `Action`s
+impl<Parent: Clone, Child> Clone for Scoped<Parent, Child> {
+    #[inline(always)]
+    fn clone(&self) -> Self {
+        Scoped(self.0.clone(), Marker)
+    }
+}
+
+impl<Parent, Child> Effects for Scoped<Parent, Child>
+where
+    Parent: Effects,
+    <Parent as Effects>::Action: Clone + From<Child> + 'static,
+    Child: 'static,
+{
+    type Action = Child;
+
+    #[inline(always)]
+    fn send(&self, action: impl Into<<Self as Effects>::Action>) {
+        self.0.send(action.into());
+    }
+
+    #[inline(always)]
+    fn task<S: Stream<Item = Child> + 'static>(&self, stream: S) -> Task {
+        self.0.task(stream.map(|action| action.into()))
+    }
+}
+
+#[doc(hidden)]
+impl<Parent, Child> Scheduler for Scoped<Parent, Child>
+where
+    Parent: Effects,
+    <Parent as Effects>::Action: From<Child> + Clone + 'static,
+{
+    type Action = Child;
+
+    #[inline(always)]
+    fn schedule(
+        &self,
+        action: Self::Action,
+        after: impl IntoIterator<Item = Delay> + 'static,
+    ) -> Task
+    where
+        Self::Action: Clone + 'static,
+    {
+        self.0.schedule(action.into(), after)
+    }
+}
+
+#[doc(hidden)]
+// `Parent` for `Effects::scope` tuples
+impl<Action: 'static> Effects for Weak<RefCell<VecDeque<Action>>> {
+    type Action = Action;
+
+    fn send(&self, action: impl Into<<Self as Effects>::Action>) {
+        if let Some(actions) = self.upgrade() {
+            actions.borrow_mut().push_back(action.into())
+        }
+    }
+
+    fn task<S: Stream<Item = Action> + 'static>(&self, stream: S) -> Task {
+        Task::new(stream)
+    }
+}
+
+#[doc(hidden)]
+impl<Action: 'static> Scheduler for Weak<RefCell<VecDeque<Action>>> {
+    type Action = Action;
+
+    fn schedule(
+        &self,
+        action: Action, //
+        delays: impl IntoIterator<Item = Delay> + 'static,
+    ) -> Task
+    where
+        Self::Action: Clone + 'static,
+    {
+        self.task(iter(delays).then(move |delay| {
+            let action = action.clone();
+
+            async move {
+                delay.await;
+                action.clone().into()
+            }
+        }))
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/effects/scheduler.rs.html b/src/composable/effects/scheduler.rs.html new file mode 100644 index 00000000..53576625 --- /dev/null +++ b/src/composable/effects/scheduler.rs.html @@ -0,0 +1,269 @@ +scheduler.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+
use std::cmp::Reverse;
+use std::collections::VecDeque;
+use std::mem::replace;
+use std::sync::{Arc, Mutex};
+use std::thread::{park, park_timeout, Builder, JoinHandle};
+use std::time::Instant;
+
+use crate::dependencies::DependencyDefault;
+use crate::effects::delay::State;
+
+/// Shared between the `Scheduler` and its polling Thread
+#[derive(Default)]
+struct Shared {
+    pub(crate) queue: Queue<Instant, Arc<Mutex<State>>>,
+}
+
+impl Shared {
+    pub fn poll(now: Instant, shared: &Mutex<Shared>) -> Option<Instant> {
+        let mut shared = shared.lock().unwrap();
+        let delays = shared.queue.drain_until(now);
+        let next = shared.queue.peek_next();
+        drop(shared); // release the `Mutex` in case any of the delayed work wants the `Scheduler`
+
+        for delay in delays {
+            let mut state = delay.lock().unwrap();
+            let waiting = replace(&mut *state, State::Ready);
+            drop(state); // release the `Mutex` before the waker is called
+
+            match waiting {
+                State::Waiting(waker) => waker.wake(),
+                _ => unreachable!(),
+            }
+        }
+
+        next
+    }
+}
+
+pub(crate) struct Scheduler {
+    shared: Arc<Mutex<Shared>>,
+    handle: Option<JoinHandle<()>>,
+}
+
+impl Default for Scheduler {
+    #[inline(never)]
+    fn default() -> Self {
+        let shared = Arc::new(Mutex::<Shared>::default());
+        let remote = shared.clone();
+
+        let handle = Builder::new()
+            .name(std::any::type_name::<Self>().into())
+            .spawn(move || loop {
+                let now = Instant::now();
+                let next = Shared::poll(now, &remote);
+
+                match next {
+                    None => park(),
+                    Some(when) => park_timeout(when.saturating_duration_since(now)),
+                }
+            })
+            .expect("scheduler thread");
+
+        Self {
+            shared,
+            handle: Some(handle),
+        }
+    }
+}
+
+impl DependencyDefault for Scheduler {}
+
+impl Scheduler {
+    pub(crate) fn new() -> Self {
+        let shared = Arc::new(Mutex::<Shared>::default());
+
+        Self {
+            shared,
+            handle: None,
+        }
+    }
+
+    pub(crate) fn poll(&self, now: Instant) -> Instant {
+        Shared::poll(now, &self.shared).unwrap_or(now)
+    }
+
+    #[inline(never)]
+    pub(crate) fn add(&self, new: Instant, state: Arc<Mutex<State>>) {
+        let mut shared = self.shared.lock().unwrap();
+        let next = shared.queue.peek_next();
+        shared.queue.insert(new, state);
+        drop(shared);
+
+        match (&self.handle, next) {
+            (Some(handle), None) => handle.thread().unpark(), // no `unpark` is scheduled yet
+            (Some(handle), Some(pending)) if new < pending => handle.thread().unpark(),
+            _ => {}
+        }
+    }
+}
+
+pub(crate) struct Queue<Key, Value> {
+    deque: VecDeque<(Reverse<Key>, Value)>,
+}
+
+// Using `#[derive(Default)]` adds a `Default` requirement to Key
+impl<Key, Value> Default for Queue<Key, Value> {
+    fn default() -> Self {
+        Queue {
+            deque: Default::default(),
+        }
+    }
+}
+
+impl<Key: Copy, Value> Queue<Key, Value> {
+    pub fn peek_next(&self) -> Option<Key> {
+        self.deque.back().map(|kv| kv.0 .0)
+    }
+}
+
+impl<Key: PartialOrd, Value> Queue<Key, Value> {
+    pub fn insert(&mut self, key: Key, value: Value) {
+        let key = Reverse(key);
+        let index = self.deque.partition_point(|x| x.0 <= key);
+        self.deque.insert(index, (key, value));
+    }
+
+    pub fn drain_until(&mut self, key: Key) -> impl Iterator<Item = Value> {
+        let key = Reverse(key);
+        let index = self.deque.partition_point(|x| x.0 < key);
+
+        // without the use of `Reverse` for the keys `split_off` would return the wrong half
+        self.deque.split_off(index).into_iter().rev().map(|kv| kv.1)
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/effects/task.rs.html b/src/composable/effects/task.rs.html new file mode 100644 index 00000000..02bd7f80 --- /dev/null +++ b/src/composable/effects/task.rs.html @@ -0,0 +1,161 @@ +task.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
use std::thread::Thread;
+
+use futures::executor::LocalSpawner;
+use futures::future::RemoteHandle;
+use futures::task::LocalSpawnExt;
+use futures::{pin_mut, Stream, StreamExt};
+
+use crate::dependencies::Dependency;
+use crate::store::channel::WeakSender;
+
+/// Asynchronous work being performed by a `Store`.
+///
+/// A [`Store`][`crate::Store`] uses a [Local Async Executor] to run its `Task`s.
+///
+/// [Local Async Executor]: https://maciej.codes/2022-06-09-local-async.html
+#[doc(hidden)]
+#[derive(Debug)]
+#[must_use = "dropping a Task cancels the underlying future"]
+pub struct Task {
+    pub(crate) handle: Option<RemoteHandle<()>>,
+    pub(crate) when: Option<std::time::Instant>,
+}
+
+/// Cloning a `Task` an empty `Task` but implementing `Clone` allows it to be
+/// used in states that use [`TestStore`]s for testing.
+impl Clone for Task {
+    fn clone(&self) -> Self {
+        Task {
+            handle: None,
+            when: None,
+        }
+    }
+}
+
+impl Task {
+    /// Detaches the task; leaving its [`Future`][`std::future`] running in the background.
+    pub fn detach(self) {
+        if let Some(handle) = self.handle {
+            handle.forget()
+        }
+    }
+
+    /// Cancels the task; meaning its [`Future`][`std::future`] won’t be polled again.
+    pub fn cancel(self) {
+        drop(self)
+    }
+
+    pub(crate) fn new<Action: 'static, S: Stream<Item = Action> + 'static>(stream: S) -> Self {
+        // Only called by “root” `Effects`, so it will be the same `Action` as used by the `Store`
+        let handle = Dependency::<Executor<Result<Action, Thread>>>::new() //
+            .and_then(|executor| match executor.actions.upgrade() {
+                None => None,
+                Some(sender) => executor
+                    .spawner
+                    .spawn_local_with_handle(async move {
+                        pin_mut!(stream);
+                        while let Some(action) = stream.next().await {
+                            sender.send(Ok(action));
+                        }
+                    })
+                    .ok(),
+            });
+
+        Task {
+            handle, // may return a `Task { handle: None }` while the `Store` is shutting down
+            when: None,
+        }
+    }
+}
+
+pub(crate) struct Executor<Action> {
+    pub(crate) spawner: LocalSpawner,
+    pub(crate) actions: WeakSender<Action>,
+}
+
+impl<Action> Executor<Action> {
+    pub(crate) fn new(spawner: LocalSpawner, actions: WeakSender<Action>) -> Self {
+        Self { spawner, actions }
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/lib.rs.html b/src/composable/lib.rs.html new file mode 100644 index 00000000..fb8021b2 --- /dev/null +++ b/src/composable/lib.rs.html @@ -0,0 +1,81 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+
#![doc = include_str!("../README.md")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))] // show features flags in documentation
+#![deny(rustdoc::broken_intra_doc_links)]
+#![deny(unsafe_code)]
+#![allow(missing_docs)]
+#![allow(dead_code)]
+
+#[doc(no_inline)]
+pub use derive_macros::*;
+#[doc(inline)]
+pub use effects::{Interval, Task};
+pub use reducer::Reducer;
+pub use store::{testing::TestClock, testing::TestStore, Store};
+
+pub mod dependencies;
+/// Optional view feature.
+#[cfg(all(feature = "unreleased", feature = "views"))]
+pub mod views;
+
+/// `Effects` are used within `Reducer`s to propagate `Action`s as side-effects of performing other
+/// `Action`s.
+///
+/// `Effects` are also `Schedulers` — able to apply modifiers to when (and how often) `Action`s. are sent.
+///
+/// This is a “trait alias” (to the actual [`Effects`][`crate::effects::Effects`] trait) to simplify
+/// `Reducer` signatures and set the lifetime to `'static`.
+pub trait Effects<Action>: effects::Effects<Action = Action> + 'static {}
+
+/// Until actual [trait aliases] are stabilized this [work around] allows the trait shown above
+/// to be used anywhere that the [original trait] can.
+///
+/// [trait aliases]: https://github.com/rust-lang/rust/issues/63063
+/// [work around]: https://github.com/rust-lang/rust/issues/41517#issuecomment-1100644808
+/// [original trait]: crate::effects::Effects
+impl<T, Action> Effects<Action> for T where T: effects::Effects<Action = Action> + 'static {}
+
+pub mod derive_macros;
+pub mod effects;
+mod reducer;
+mod store;
+
\ No newline at end of file diff --git a/src/composable/reducer/mod.rs.html b/src/composable/reducer/mod.rs.html new file mode 100644 index 00000000..098d7dd7 --- /dev/null +++ b/src/composable/reducer/mod.rs.html @@ -0,0 +1,165 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+
use std::ops::DerefMut;
+
+use crate::Effects;
+
+/// `Reducer`s are responsible for updating a `Store`’s state in response to its `Action`s.
+pub trait Reducer {
+    /// All of the possible actions that can be used to modify state.
+    type Action;
+
+    /// Both unit tests and command line applications often need to return their `Store`’s final
+    /// state. Therefore `Store`’s [`into_inner`] method shuts down the `Store` and converts its
+    /// `Reducer` into its `Output` type.
+    ///
+    /// Using a separate `Output` type, rather than returning the `Reducer` itself, allows the
+    /// `Store`s to support `Reducer` types that are not [`Send`].
+    ///  
+    /// - `Reducer`s that do not need to support [`into_inner`] should use declare
+    ///   `type Output = Self;` as it is a simple, recognizable default.
+    /// - A `Reducer` that _is_ `Send` can also default to `type Output = Self;`.
+    /// - Otherwise, the `Reducer` will need to declare an `Output` type that _is_ `Send` and
+    ///   that can be crated [`From`] the `Reducer`’s state.
+    ///
+    /// ```rust
+    /// # use std::rc::Rc;
+    /// # use std::cell::Cell;
+    /// # use composable::{Effects, Reducer, Store};
+    /// # #[derive(Default)]
+    /// struct State {
+    ///     n: Rc<Cell<usize>>, // Rc<Cell<…>> is not Send
+    /// };
+    ///
+    /// enum Action { /* … */ }
+    ///
+    /// impl Reducer for State {
+    ///     type Action = Action;
+    ///     type Output = usize; // but the usize itself _is_
+    ///
+    ///     fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>) { /**/ }
+    /// }
+    ///
+    /// impl From<State> for usize {
+    ///     fn from(value: State) -> Self {
+    ///         Cell::into_inner(Rc::into_inner(value.n).unwrap_or_default())
+    ///     }
+    /// }
+    /// # let store = Store::<State>::default();
+    /// ```
+    ///
+    /// [`into_inner`]: crate::Store::into_inner
+    ///
+    /// In short, you can use `type Output = Self;` until the compiler says that you can’t.
+    type Output;
+
+    /// Updates the `Reducer`’s state in response to the action received.
+    ///
+    /// Additional `Action`s that need to be performed as a side-effect of an `Action` should be
+    /// [invoked][`crate::effects::Effects`] on `effects`.
+    #[doc = include_str!("README.md")]
+    fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>);
+}
+
+impl<T: Reducer> Reducer for Box<T> {
+    type Action = T::Action;
+
+    type Output = T::Output;
+
+    fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>) {
+        self.deref_mut().reduce(action, effects)
+    }
+}
+
+impl<T: Reducer> Reducer for Option<T> {
+    type Action = T::Action;
+
+    type Output = Option<T::Output>;
+
+    fn reduce(&mut self, action: Self::Action, effects: impl Effects<Self::Action>) {
+        if let Some(state) = self {
+            state.reduce(action, effects)
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/store/channel.rs.html b/src/composable/store/channel.rs.html new file mode 100644 index 00000000..8aa5907e --- /dev/null +++ b/src/composable/store/channel.rs.html @@ -0,0 +1,315 @@ +channel.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+
use std::collections::VecDeque;
+use std::sync::{Arc, Mutex, MutexGuard, Weak};
+use std::task::{Context, Poll, Waker};
+use std::{mem::swap, pin::Pin};
+
+use futures::Stream;
+use pin_project::pin_project;
+
+struct Shared<T> {
+    queue: VecDeque<T>,
+    waker: Option<Waker>,
+}
+
+impl<T> Default for Shared<T> {
+    fn default() -> Self {
+        Shared {
+            queue: Default::default(),
+            waker: Default::default(),
+        }
+    }
+}
+
+#[derive(Default)]
+#[pin_project] // See: https://blog.adamchalmers.com/pin-unpin/
+pub struct Receiver<T> {
+    shared: Arc<Mutex<Shared<T>>>,
+    buffer: VecDeque<T>,
+}
+
+impl<T> Stream for Receiver<T> {
+    type Item = T;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let inner = &mut self.project();
+
+        if let Some(value) = inner.buffer.pop_front() {
+            return Poll::Ready(Some(value));
+        }
+
+        let mut shared = inner.shared.lock().unwrap_or_else(|err| err.into_inner());
+        let external = &mut shared.queue;
+
+        match external.pop_front() {
+            Some(value) => {
+                // move all other pending values (if any) into the (un-Mutex’d) internal buffer
+                swap(external, &mut inner.buffer);
+                Poll::Ready(Some(value))
+            }
+            None if Arc::strong_count(&inner.shared) == 1 => {
+                Poll::Ready(None) // no receivers remaining
+            }
+            None => {
+                match shared.waker.as_mut() {
+                    None => shared.waker = Some(cx.waker().clone()),
+                    Some(waker) => waker.clone_from(cx.waker()),
+                };
+
+                Poll::Pending
+            }
+        }
+    }
+}
+
+pub struct Sender<T> {
+    shared: Arc<Mutex<Shared<T>>>,
+}
+
+impl<T> Clone for Sender<T> {
+    fn clone(&self) -> Self {
+        Sender {
+            shared: self.shared.clone(),
+        }
+    }
+}
+
+impl<T> Drop for Sender<T> {
+    fn drop(&mut self) {
+        self.wake_after(|_| { /* drop */ })
+    }
+}
+
+impl<T> Sender<T> {
+    pub fn send(&self, value: T) {
+        self.wake_after(move |mut shared| shared.queue.push_back(value))
+    }
+
+    pub fn downgrade(&self) -> WeakSender<T> {
+        WeakSender {
+            shared: Arc::downgrade(&self.shared),
+        }
+    }
+
+    /// Perform some work and then, if a `Receiver` was waiting, wake it.
+    ///
+    /// Note that the [`Waker`] will only ever be called once for each time it
+    /// has entered the [`Poll::Pending`] state. Regardless of how many times
+    /// `wake_after` is called.
+    fn wake_after<F: FnOnce(MutexGuard<Shared<T>>)>(&self, f: F) {
+        let mut shared = self
+            .shared
+            .lock() //
+            .unwrap_or_else(|err| err.into_inner());
+
+        let waker = shared.waker.take(); // there are no “extra” wakes
+        f(shared);
+
+        if let Some(waker) = waker {
+            waker.wake() // wake _after_ the `MutexGuard` has been dropped by `f(…)`
+        }
+    }
+}
+
+pub struct WeakSender<T> {
+    shared: Weak<Mutex<Shared<T>>>,
+}
+
+impl<T> Clone for WeakSender<T> {
+    fn clone(&self) -> Self {
+        WeakSender {
+            shared: self.shared.clone(),
+        }
+    }
+}
+
+impl<T> WeakSender<T> {
+    pub fn upgrade(&self) -> Option<Sender<T>> {
+        self.shared
+            .upgrade() //
+            .map(|shared| Sender { shared })
+    }
+}
+
+pub struct WeakReceiver<T> {
+    shared: Weak<Mutex<Shared<T>>>,
+}
+
+impl<T> WeakReceiver<T> {
+    pub fn upgrade(self) -> Option<Receiver<T>> {
+        self.shared
+            .upgrade() //
+            .map(|shared| Receiver {
+                shared,
+                buffer: Default::default(),
+            })
+    }
+}
+
+pub fn channel<T>() -> (Sender<T>, WeakReceiver<T>) {
+    let shared = Default::default();
+
+    let recv = WeakReceiver {
+        shared: Arc::downgrade(&shared),
+    };
+    let send = Sender { shared };
+
+    (send, recv)
+}
+
\ No newline at end of file diff --git a/src/composable/store/mod.rs.html b/src/composable/store/mod.rs.html new file mode 100644 index 00000000..aa79d17f --- /dev/null +++ b/src/composable/store/mod.rs.html @@ -0,0 +1,155 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+
use std::thread::{JoinHandle, Thread};
+
+use channel::Sender;
+
+use crate::Reducer;
+
+pub(crate) mod channel;
+mod runtime;
+
+pub(crate) mod testing;
+
+#[doc = include_str!("README.md")]
+pub struct Store<State: Reducer> {
+    sender: Sender<Result<<State as Reducer>::Action, Thread>>,
+    handle: JoinHandle<<State as Reducer>::Output>,
+}
+
+impl<State: Reducer> Store<State> {
+    /// Creates a new `Store` with `state` as its initial state.
+    ///
+    /// If `State` is not [`Send`], then [`new`][`Store::new`] or [`default`][`Store::default`]
+    /// can be used instead.
+    pub fn with_initial(state: State) -> Self
+    where
+        State: Send + 'static,
+        <State as Reducer>::Action: Send,
+        <State as Reducer>::Output: Send + From<State>,
+    {
+        Store::runtime(|| state)
+    }
+
+    /// Creates a new `Store` with its initial state generated by a function.
+    ///
+    /// Useful if `State` is not [`Send`], but the arguments used to construct it are.
+    pub fn new<F>(with: F) -> Self
+    where
+        F: (FnOnce() -> State) + Send + 'static,
+        <State as Reducer>::Action: Send + 'static,
+        <State as Reducer>::Output: Send + From<State> + 'static,
+    {
+        Store::runtime(with)
+    }
+
+    /// Calls the `Store`’s [`Reducer`][`crate::Reducer`] with `action`.
+    ///
+    /// Takes an [`Into<Action>`] so that both child and parent `Action`s may be sent easily.
+    pub fn send(&self, action: impl Into<<State as Reducer>::Action>) {
+        self.sender.send(Ok(action.into()))
+    }
+
+    /// Stops the `Store`’s runtime and returns its current `state` value.  
+    ///
+    /// # Note
+    /// Care should be exercised when using this method in applications that utilize
+    /// asynchronous [`Effects`][`crate::effects::Effects`]. `into_inner` makes a “best effort”
+    /// to wait until any pending tasks are completed but it is not guaranteed.
+    pub fn into_inner(self) -> <State as Reducer>::Output {
+        self.sender.send(Err(std::thread::current()));
+        std::thread::park(); // waiting for any async tasks to finish up
+
+        drop(self.sender); // ends the runtime’s (outer) while-let
+        std::thread::yield_now(); // give it time to shut down
+        self.handle.join().unwrap()
+    }
+}
+
+impl<State: Reducer> Default for Store<State>
+where
+    State: Default,
+    <State as Reducer>::Action: Send + 'static,
+    <State as Reducer>::Output: Send + From<State> + 'static,
+{
+    /// Creates a new `Store` with a default initial state.
+    fn default() -> Self {
+        Store::new(|| State::default())
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/store/runtime.rs.html b/src/composable/store/runtime.rs.html new file mode 100644 index 00000000..b800256d --- /dev/null +++ b/src/composable/store/runtime.rs.html @@ -0,0 +1,387 @@ +runtime.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+
use std::cell::RefCell;
+use std::collections::VecDeque;
+use std::rc::Rc;
+use std::thread::{Builder, Thread};
+
+use futures::executor::LocalPool;
+use futures::task::LocalSpawnExt;
+use futures::{pin_mut, StreamExt};
+
+use crate::dependencies::with_dependency;
+use crate::effects::Executor;
+use crate::reducer::Reducer;
+use crate::store::channel::{channel, WeakSender};
+use crate::store::Store;
+
+impl<State: Reducer> Store<State> {
+    pub(crate) fn runtime<F>(with: F) -> Self
+    where
+        F: (FnOnce() -> State) + Send + 'static,
+        <State as Reducer>::Action: Send + 'static,
+        <State as Reducer>::Output: Send + From<State> + 'static,
+    {
+        let (sender, receiver) = channel();
+        let actions: WeakSender<Result<<State as Reducer>::Action, Thread>> = sender.downgrade();
+
+        let handle = Builder::new()
+            .name(std::any::type_name::<State>().into())
+            .spawn(move || {
+                let mut unthreaded = LocalPool::new();
+                let spawner = unthreaded.spawner();
+
+                let mut state = with();
+                let receiver = receiver.upgrade().unwrap();
+                let effects = Rc::new(RefCell::new(VecDeque::new()));
+
+                let executor = Executor::new(spawner.clone(), actions);
+
+                with_dependency(executor, || {
+                    unthreaded.run_until(async {
+                        pin_mut!(receiver);
+                        while let Some(result) = receiver.next().await {
+                            match result {
+                                Ok(action) => {
+                                    state.reduce(action, Rc::downgrade(&effects));
+
+                                    // wrapping the `borrow_mut` in a closure to ensure that the
+                                    // `borrow_mut` is dropped immediately so that the action is
+                                    // free to push further actions to `effects`
+                                    let next = || effects.borrow_mut().pop_front();
+
+                                    while let Some(action) = next() {
+                                        state.reduce(action, Rc::downgrade(&effects));
+                                    }
+                                }
+                                Err(parked) => {
+                                    spawner
+                                        // `unpark` a thread that is waiting for the store to shut down;
+                                        //  we use a future so that it happens after other (waiting) futures
+                                        //
+                                        //  See: `Store::into_inner` for the other side of this
+                                        .spawn_local(async move {
+                                            parked.unpark();
+                                        })
+                                        .expect("unpark");
+                                }
+                            }
+                        }
+                    });
+
+                    state.into()
+                })
+            })
+            .unwrap();
+
+        Store { sender, handle }
+    }
+}
+
+#[cfg(test)]
+pub mod tests {
+    use std::sync::{Arc, Mutex};
+
+    #[cfg(not(miri))]
+    use ntest_timeout::timeout;
+
+    use crate::Effects;
+
+    use super::*;
+
+    #[derive(Clone, Debug, Default)]
+    pub struct State {
+        pub characters: Arc<Mutex<Vec<char>>>,
+    }
+
+    #[derive(Clone, Debug, PartialEq)]
+    pub enum Action {
+        Internal(char),
+        External(char),
+    }
+
+    impl Reducer for State {
+        type Action = Action;
+        type Output = Self;
+
+        fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+            use Action::*;
+
+            match action {
+                Internal(ch) => self.characters.lock().unwrap().push(ch),
+                External(ch) => {
+                    self.characters.lock().unwrap().push(ch);
+
+                    if ch == '1' {
+                        effects.send(Internal('A'));
+                        effects.send(Internal('B'));
+                        effects.send(Internal('C'));
+                        effects.send(Internal('D'));
+                    }
+                }
+            }
+        }
+    }
+
+    impl PartialEq for State {
+        fn eq(&self, other: &Self) -> bool {
+            let lhs = self.characters.lock().unwrap();
+            let rhs = other.characters.lock().unwrap();
+
+            *lhs == *rhs
+        }
+    }
+
+    #[test]
+    /// Certain domains rely upon a chain of internal effects being uninterruptible by any
+    /// additional external actions. This test helps ensure that guarantee.
+    ///
+    /// # Note:
+    ///
+    /// - Normal tests should use [`clock`]s and a [`TestStore`] rather than the brute-force
+    ///   loop and thread manipulations used here.
+    ///
+    fn test_action_ordering_guarantees() {
+        let characters = Arc::new(Mutex::new(Default::default()));
+        let store = Store::with_initial(State {
+            characters: characters.clone(),
+        });
+
+        use Action::*;
+        store.send(External('1'));
+        store.send(External('2'));
+        store.send(External('3'));
+
+        loop {
+            {
+                let values = characters.lock().unwrap();
+                if values.len() == 7 {
+                    break;
+                }
+            }
+
+            std::thread::yield_now();
+        }
+
+        let values = characters.lock().unwrap();
+        // '1'’s side-effects happen BEFORE the other actions are dispatched
+        assert_eq!(*values, vec!['1', 'A', 'B', 'C', 'D', '2', '3']);
+    }
+
+    #[test]
+    #[cfg(not(miri))]
+    #[timeout(1000)]
+    /// # Note
+    /// If this test **timeout**s, the [`join`] in [`Store::into_inner`] is hanging
+    ///
+    /// [`join`]: std::thread::JoinHandle::join
+    fn test_into_inner_returns() {
+        #[derive(Default)]
+        struct State;
+
+        #[derive(Debug)]
+        enum Action {}
+
+        impl Reducer for State {
+            type Action = Action;
+            type Output = Self;
+
+            fn reduce(&mut self, _action: Action, _effects: impl Effects<Action>) {}
+        }
+
+        let store = Store::<State>::default();
+        store.into_inner();
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/store/testing/clock.rs.html b/src/composable/store/testing/clock.rs.html new file mode 100644 index 00000000..29e3b01f --- /dev/null +++ b/src/composable/store/testing/clock.rs.html @@ -0,0 +1,139 @@ +clock.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+
use std::time::Duration;
+
+/// When testing, it is important to have control over the (simulated) passage of time.
+///
+/// …
+/// ```rust
+/// # use std::time::Duration;
+/// # use composable::*;
+/// #
+/// #[derive(Clone, Debug, Default)]
+///  struct State {
+///      previous: Option<Task>,
+///      n: usize,
+///  }
+///
+/// # impl PartialEq for State {
+/// #     fn eq(&self, other: &Self) -> bool {
+/// #         self.n.eq(&other.n)
+/// #     }
+/// # }
+/// #
+/// #[derive(Clone, Debug, PartialEq)]
+/// enum Action {
+///     Send,
+///     Recv,
+/// }
+///
+/// use Action::*;
+///
+/// impl Reducer for State {
+///     type Action = Action;
+///     type Output = Self;
+///
+///     fn reduce(&mut self, action: Action, effects: impl Effects<Action>) {
+///         match action {
+///             Send => {
+///                 effects.debounce(
+///                     Recv,
+///                     &mut self.previous,
+///                     Interval::Trailing(Duration::from_secs(4)),
+///                 );
+///             }
+///             Recv => {
+///                 self.n += 1;
+///             }
+///         }
+///     }
+/// }
+///
+/// let mut store = TestStore::<State>::default();
+/// let no_change: fn(&mut State) = |State| {};
+///
+/// store.send(Send, no_change);
+/// store.advance(Duration::from_secs(3));
+///
+/// store.send(Send, no_change);
+/// store.advance(Duration::from_secs(8));
+/// store.recv(Recv, |state| state.n = 1);
+///
+/// store.send(Send, no_change);
+/// store.advance(Duration::from_secs(1));
+/// store.advance(Duration::from_secs(1));
+/// store.advance(Duration::from_secs(1));
+/// store.advance(Duration::from_secs(1));
+/// store.recv(Recv, |state| state.n = 2);
+/// ```
+pub trait TestClock {
+    fn advance(&mut self, duration: Duration);
+}
+
\ No newline at end of file diff --git a/src/composable/store/testing/mod.rs.html b/src/composable/store/testing/mod.rs.html new file mode 100644 index 00000000..d39f2331 --- /dev/null +++ b/src/composable/store/testing/mod.rs.html @@ -0,0 +1,525 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+
use std::cell::RefCell;
+use std::collections::VecDeque;
+use std::fmt::Debug;
+use std::rc::Rc;
+use std::time::{Duration, Instant};
+
+use futures::executor::{LocalPool, LocalSpawner};
+use futures::stream::iter;
+use futures::task::LocalSpawnExt;
+use futures::{pin_mut, Stream, StreamExt};
+
+pub use clock::TestClock;
+
+use crate::dependencies::{guard::Guard, Dependency};
+use crate::effects::scheduler::Scheduler as Timer;
+use crate::effects::{Delay, Effects, Scheduler};
+use crate::reducer::Reducer;
+use crate::Task;
+
+mod clock;
+
+#[doc = include_str!("README.md")]
+pub struct TestStore<State: Reducer>
+where
+    <State as Reducer>::Action: Debug,
+{
+    state: Option<State>, // `Option` so that `into_inner` does not break `Drop`
+    pool: LocalPool,
+
+    // external polling
+    inner: Rc<RefCell<Inner<<State as Reducer>::Action>>>,
+    scheduler: Guard<Timer>,
+}
+
+impl<State: Reducer> Default for TestStore<State>
+where
+    State: Default,
+    <State as Reducer>::Action: Debug,
+{
+    fn default() -> Self {
+        Self::new(|| State::default())
+    }
+}
+
+impl<State: Reducer> Drop for TestStore<State>
+where
+    <State as Reducer>::Action: Debug,
+{
+    #[track_caller]
+    fn drop(&mut self) {
+        assert!(
+            self.inner.borrow().effects.is_empty(),
+            "one or more extra actions were not tested for: {:#?}",
+            self.inner
+                .borrow_mut()
+                .effects
+                .drain(..)
+                .collect::<Vec<_>>()
+        );
+    }
+}
+
+impl<State: Reducer> TestClock for TestStore<State>
+where
+    <State as Reducer>::Action: Debug,
+{
+    fn advance(&mut self, duration: Duration) {
+        let mut inner = self.inner.borrow_mut();
+        let now = inner.now + duration;
+        inner.now = now;
+        drop(inner);
+
+        let timer = Dependency::<Timer>::new();
+
+        loop {
+            self.pool.run_until_stalled();
+            timer.poll(now);
+
+            if self.pool.try_run_one() == false {
+                break;
+            }
+        }
+    }
+}
+
+impl<State: Reducer> TestStore<State>
+where
+    <State as Reducer>::Action: Debug,
+{
+    /// Creates a new `Store` with its initial state generated by a function.
+    pub fn new<F>(with: F) -> Self
+    where
+        F: (FnOnce() -> State),
+    {
+        Self::with_initial(with())
+    }
+
+    /// Creates a new `Store` with `state` as its initial state.
+    pub fn with_initial(state: State) -> Self {
+        let pool = LocalPool::new();
+        let spawner = pool.spawner();
+
+        Self {
+            state: Some(state),
+            inner: Inner::new(spawner),
+            scheduler: Guard::new(Timer::new()),
+            pool,
+        }
+    }
+    /// Calls the `Store`’s [`Reducer`][`crate::Reducer`] with `action` and asserts the
+    /// expected state changes.
+    #[track_caller]
+    pub fn send(&mut self, action: <State as Reducer>::Action, assert: impl FnOnce(&mut State))
+    where
+        State: Clone + Debug + PartialEq,
+        <State as Reducer>::Action: 'static,
+    {
+        let mut expected = self.state.clone();
+        assert(expected.as_mut().unwrap());
+
+        assert!(
+            self.inner.borrow().effects.is_empty(),
+            "an extra action was received: {:#?}",
+            self.inner
+                .borrow_mut()
+                .effects
+                .drain(..)
+                .collect::<Vec<_>>()
+        );
+
+        self.state
+            .as_mut()
+            .unwrap()
+            .reduce(action, self.inner.clone());
+        assert_eq!(self.state, expected);
+    }
+
+    /// Checks that the `Store`’s [`Reducer`][`crate::Reducer`] was called with `action`
+    /// and asserts the expected state changes.
+    #[track_caller]
+    pub fn recv(&mut self, action: <State as Reducer>::Action, assert: impl FnOnce(&mut State))
+    where
+        State: Clone + Debug + PartialEq,
+        <State as Reducer>::Action: Debug + PartialEq + 'static,
+    {
+        let mut expected = self.state.clone();
+        assert(expected.as_mut().unwrap());
+
+        let received = self
+            .inner
+            .borrow_mut()
+            .effects
+            .pop_front()
+            .expect("no action received");
+        assert_eq!(received, action);
+
+        self.state
+            .as_mut()
+            .unwrap()
+            .reduce(action, self.inner.clone());
+        assert_eq!(self.state, expected);
+    }
+
+    /// Waits until all scheduled tasks have completed.
+    ///
+    /// A timeout should be added to tests calling `wait()` to ensure that it
+    /// does not wait forever if there are bugs in the asynchronous tasks.
+    /// For example
+    ///
+    /// - [ntest][ntest] provides a [timeout][timeout] attribute macro, while
+    /// - [divan][divan] has a [max_time][max_time] parameter for its bench macro.
+    ///
+    /// [ntest]: https://crates.io/crates/ntest
+    /// [divan]: https://crates.io/crates/divan
+    ///
+    /// [timeout]: https://docs.rs/ntest/latest/ntest/attr.timeout.html
+    /// [max_time]: https://docs.rs/divan/0.1.14/divan/attr.bench.html#max_time
+    pub fn wait(&mut self) {
+        self.pool.run()
+    }
+
+    /// Consumes the `Store` and returns its current `state` value.
+    pub fn into_inner(mut self) -> <State as Reducer>::Output
+    where
+        State: Into<<State as Reducer>::Output>,
+    {
+        self.state.take().unwrap().into()
+    }
+}
+
+struct Inner<Action> {
+    // queue: Queue<Instant, Action>,
+    effects: VecDeque<Action>,
+    spawner: LocalSpawner,
+    now: Instant,
+}
+
+impl<Action> Effects for Rc<RefCell<Inner<Action>>>
+where
+    Action: Debug + 'static,
+{
+    type Action = Action;
+
+    fn send(&self, action: impl Into<<Self as Effects>::Action>) {
+        self.borrow_mut().effects.push_back(action.into());
+    }
+
+    fn task<S: Stream<Item = <Self as Effects>::Action> + 'static>(&self, stream: S) -> Task {
+        let effects = self.clone();
+        let spawner = self.borrow().spawner.clone();
+
+        let handle = spawner
+            .spawn_local_with_handle(async move {
+                pin_mut!(stream);
+                while let Some(action) = stream.next().await {
+                    effects.send(action);
+                }
+            })
+            .ok();
+
+        Task { handle, when: None }
+    }
+}
+
+impl<Action> Scheduler for Rc<RefCell<Inner<Action>>>
+where
+    Action: Debug + 'static,
+{
+    type Action = Action;
+
+    fn now(&self) -> Instant {
+        self.borrow().now
+    }
+
+    fn schedule(
+        &self,
+        action: Self::Action,
+        delays: impl IntoIterator<Item = Delay> + 'static,
+    ) -> Task
+    where
+        Self::Action: Clone + 'static,
+    {
+        self.task(iter(delays).then(move |delay| {
+            let action = action.clone();
+
+            async move {
+                delay.await;
+                action.clone().into()
+            }
+        }))
+    }
+}
+
+impl<Action> Inner<Action> {
+    fn new(spawner: LocalSpawner) -> Rc<RefCell<Self>> {
+        Rc::new(RefCell::new(Self {
+            effects: Default::default(),
+            now: Instant::now().into(),
+            spawner,
+        }))
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/gesture/mod.rs.html b/src/composable/views/gesture/mod.rs.html new file mode 100644 index 00000000..50484e2b --- /dev/null +++ b/src/composable/views/gesture/mod.rs.html @@ -0,0 +1,105 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+
use std::cell::Cell;
+
+use crate::dependencies::DependencyDefault;
+
+mod recognizer;
+pub use recognizer::*;
+
+mod tap;
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub struct Id(pub(crate) std::num::NonZeroU128);
+
+#[doc(hidden)]
+impl TryFrom<u128> for Id {
+    type Error = std::num::TryFromIntError;
+
+    fn try_from(value: u128) -> Result<Self, Self::Error> {
+        Ok(Self(value.try_into()?))
+    }
+}
+
+#[non_exhaustive] // must use `State::default()`
+#[derive(Copy, Clone, Default, Eq, PartialEq)]
+pub struct Values {
+    pub active: Option<Id>,
+    pub hover: Option<Id>,
+    pub focus: Option<Id>,
+}
+
+impl DependencyDefault for Values {}
+
+/// The user interface state carried between cycles by the application.
+///
+/// ```
+/// # use composable::views::gesture::{Id, State};
+/// let state = State::default();
+///
+/// let mut values = state.get();
+/// # let id: Id = 1u128.try_into().unwrap();
+/// values.active = Some(id);
+///
+/// // …
+///
+/// state.set(values);
+///
+/// ```
+pub type State = Cell<Values>;
+
+#[test]
+fn confirm_id_niche_optimization() {
+    assert_eq!(std::mem::size_of::<Id>(), std::mem::size_of::<u128>());
+}
+
\ No newline at end of file diff --git a/src/composable/views/gesture/recognizer.rs.html b/src/composable/views/gesture/recognizer.rs.html new file mode 100644 index 00000000..8d4f1a53 --- /dev/null +++ b/src/composable/views/gesture/recognizer.rs.html @@ -0,0 +1,91 @@ +recognizer.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+
use crate::dependencies::Dependency;
+use crate::views::{Bounds, Gesture, Point};
+
+use super::{Id, State};
+
+///
+#[inline(never)]
+pub fn recognizer(id: Id, gesture: Gesture, location: Point, bounds: Bounds) -> Option<Response> {
+    let current = Dependency::<State>::new();
+    let mut state = current.get();
+
+    let id = Some(id);
+    let inside = (state.active.is_none() || state.active == id) && bounds.contains(location);
+    // only ‘inside’ if someone else isn’t already active
+
+    const Y: bool = true; // to make the table below easier to read
+    const N: bool = false;
+
+    use Response::*;
+    #[rustfmt::skip] // keep the table compact and legible
+    let response = match (state.active == id, state.hover == id, inside, gesture) {
+        (_, _, Y, Gesture::Began {..}) => { state.active = id; state.hover = id; Some(DownInside) },
+        (Y, _, Y, Gesture::Ended {..}) => { state.active = None; state.hover = None; Some(UpInside) },
+        (Y, _, N, Gesture::Ended {..}) => { state.active = None; state.hover = None; Some(UpOutside) },
+        (Y, Y, Y, Gesture::Moved {..}) => Some(DragInside),
+        (Y, N, N, Gesture::Moved {..}) => Some(DragOutside),
+        (Y, Y, N, Gesture::Moved {..}) => { state.hover = None; Some(DragExit) },
+        (Y, N, Y, Gesture::Moved {..}) => { state.hover = id; Some(DragEnter) },
+        _ => None
+    };
+
+    current.set(state);
+    response
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Response {
+    DownInside,
+    UpInside,
+    UpOutside,
+    DragInside,
+    DragExit,
+    DragOutside,
+    DragEnter,
+}
+
\ No newline at end of file diff --git a/src/composable/views/gesture/tap.rs.html b/src/composable/views/gesture/tap.rs.html new file mode 100644 index 00000000..70cec49b --- /dev/null +++ b/src/composable/views/gesture/tap.rs.html @@ -0,0 +1,83 @@ +tap.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
use crate::views::gesture::{self, Id};
+use crate::views::{Bounds, Event, Output, Point, Size, View};
+use crate::Effects;
+
+pub struct TapGesture<V, E, A> {
+    id: Id,
+    view: V,
+    action: A,
+    effects: E,
+}
+
+impl<V, E, A> View for TapGesture<V, E, A>
+where
+    V: View,
+    E: Effects<A>,
+    A: Clone,
+{
+    #[inline(always)]
+    fn size(&self) -> Size {
+        self.view.size()
+    }
+
+    #[inline]
+    fn event(&self, event: Event, offset: Point, bounds: Bounds) {
+        if let Ok(gesture) = event.try_into() {
+            if let Some(gesture::Response::UpInside) = gesture::recognizer(
+                self.id,
+                gesture,
+                offset,
+                Bounds::from_origin_and_size(bounds.min, self.size()),
+            ) {
+                self.effects.send(self.action.clone())
+            }
+        }
+    }
+
+    #[inline(always)]
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {
+        self.view.draw(bounds, onto)
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/layout/mod.rs.html b/src/composable/views/layout/mod.rs.html new file mode 100644 index 00000000..b0ce2d4b --- /dev/null +++ b/src/composable/views/layout/mod.rs.html @@ -0,0 +1,329 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+
#![allow(unused_imports)]
+use crate::views::{Bounds, Event, Output, Point, Size, View}; // some of these are used in the macro
+
+pub use spacing::Spacer;
+
+mod spacing;
+
+#[doc(hidden)]
+struct Horizontal<T>(T);
+
+macro_rules! tuple_impl {
+    ( $($val:ident)+ ) => {
+        #[doc(hidden)]
+        #[allow(non_snake_case)]
+        #[allow(unused_variables)]
+        impl<$($val: View),+> View for ( $($val,)+ ) {
+            #[inline]
+            fn size(&self) -> Size {
+                let ( $(ref $val,)+ ) = self;
+
+                let mut size = Size::zero();
+                $(
+                    let next = $val.size();
+                    size = Size::new(f32::max(size.width, next.width), size.height + next.height);
+                )+
+
+                size
+            }
+
+            #[inline]
+            fn event(&self, event: Event, offset: Point, mut bounds: Bounds) {
+                self.update_layout(self.size(), bounds);
+
+                let ( $(ref $val,)+ ) = self;
+                $(
+                    $val.event(event, offset, bounds);
+                    bounds.min.y += $val.size().height;
+                    bounds.min.y = f32::min(bounds.min.y, bounds.max.y);
+                )+
+            }
+
+            #[inline]
+            fn draw(&self, mut bounds: Bounds, onto: &mut impl Output) {
+                self.update_layout(self.size(), bounds);
+
+                let ( $(ref $val,)+ ) = self;
+                $(
+                    $val.draw(bounds, onto);
+                    bounds.min.y += $val.size().height;
+                    bounds.min.y = f32::min(bounds.min.y, bounds.max.y);
+                )+
+            }
+
+            fn update_layout(&self, size: Size, bounds: Bounds) {
+                let ( $(ref $val,)+ ) = self;
+
+                let mut n = 0;
+                $( n += $val.needs_layout() as u32; )+ // effectively const
+
+                if n != 0 {
+                    let mut height = 0.0;
+                    $( height += $val.size().height; )+
+
+                    let space = f32::max((bounds.height() - height) / n as f32, 0.0);
+                    $( $val.update_layout(Size::new(0.0, space), bounds); )+
+                }
+            }
+
+            #[inline(always)]
+            fn across(self) -> impl View {
+                Horizontal(self)
+            }
+        }
+
+        #[doc(hidden)]
+        #[allow(non_snake_case)]
+        #[allow(unused_variables)]
+        impl<$($val: View),+> View for Horizontal<( $($val,)+ )> {
+            #[inline]
+            fn size(&self) -> Size {
+                let ( $(ref $val,)+ ) = self.0;
+
+                let mut size = Size::zero();
+                $(
+                    let next = $val.size();
+                    size = Size::new(size.width + next.width, f32::max(size.height, next.height));
+                )+
+
+                size
+            }
+
+            #[inline]
+            fn event(&self, event: Event, offset: Point, mut bounds: Bounds) {
+                self.update_layout(self.size(), bounds);
+
+                let ( $(ref $val,)+ ) = self.0;
+                $(
+                    $val.event(event, offset, bounds);
+                    bounds.min.x += $val.size().width;
+                    bounds.min.x = f32::min(bounds.min.x, bounds.max.x);
+                )+
+            }
+
+            #[inline]
+            fn draw(&self, mut bounds: Bounds, onto: &mut impl Output) {
+                self.update_layout(self.size(), bounds);
+
+                let ( $(ref $val,)+ ) = self.0;
+                $(
+                    $val.draw(bounds, onto);
+                    bounds.min.x += $val.size().width;
+                    bounds.min.x = f32::min(bounds.min.x, bounds.max.x);
+                )+
+            }
+
+            #[inline(always)]
+            fn needs_layout(&self) -> bool {
+                self.0.needs_layout()
+            }
+
+            fn update_layout(&self, size: Size, bounds: Bounds) {
+                let ( $(ref $val,)+ ) = self.0;
+
+                let mut n = 0;
+                $( n += $val.needs_layout() as u32;)+
+
+                if n != 0 {
+                    let mut width = 0.0;
+                    $( width += $val.size().width; )+
+
+                    let space = f32::max((bounds.width() - width) / n as f32, 0.0);
+                    $( $val.update_layout(Size::new(space, 0.0), bounds); )+
+                }
+            }
+        }
+    };
+}
+
+tuple_impl! { A }
+tuple_impl! { A B }
+tuple_impl! { A B C }
+tuple_impl! { A B C D }
+tuple_impl! { A B C D E }
+tuple_impl! { A B C D E F }
+tuple_impl! { A B C D E F G }
+tuple_impl! { A B C D E F G H }
+tuple_impl! { A B C D E F G H I }
+tuple_impl! { A B C D E F G H I J }
+tuple_impl! { A B C D E F G H I J K }
+tuple_impl! { A B C D E F G H I J K L }
+tuple_impl! { A B C D E F G H I J K L M }
+tuple_impl! { A B C D E F G H I J K L M N }
+tuple_impl! { A B C D E F G H I J K L M N O }
+tuple_impl! { A B C D E F G H I J K L M N O P }
+tuple_impl! { A B C D E F G H I J K L M N O P Q }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V W }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V W X }
+tuple_impl! { A B C D E F G H I J K L M N O P Q R S T U V W X Y }
+// up to 25 views are supported
+
\ No newline at end of file diff --git a/src/composable/views/layout/spacing.rs.html b/src/composable/views/layout/spacing.rs.html new file mode 100644 index 00000000..38133cea --- /dev/null +++ b/src/composable/views/layout/spacing.rs.html @@ -0,0 +1,111 @@ +spacing.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+
use std::cell::OnceCell;
+
+use crate::views::{Bounds, Event, Output, Point, Size, View};
+
+pub struct Spacer(pub(crate) OnceCell<Size>);
+
+impl Spacer {
+    #[inline(always)]
+    pub fn fill() -> Self {
+        Spacer(OnceCell::new()) // a flexible spacer has no size (yet)
+    }
+
+    #[inline(always)]
+    pub fn fixed(width: f32, height: f32) -> Self {
+        let spacer = Self::fill();
+        spacer.0.set(Size::new(width, height)).ok();
+        spacer
+    }
+
+    #[inline(always)]
+    pub fn width(width: f32) -> Self {
+        Spacer::fixed(width, 1.0)
+    }
+
+    #[inline(always)]
+    pub fn height(height: f32) -> Self {
+        Spacer::fixed(1.0, height)
+    }
+
+    #[inline(always)]
+    pub fn empty() -> Self {
+        Self::fixed(0.0, 0.0)
+    }
+}
+
+#[allow(unused_variables)]
+impl View for Spacer {
+    #[inline]
+    fn size(&self) -> Size {
+        self.0.get().cloned().unwrap_or_default()
+    }
+
+    #[inline(always)]
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {}
+
+    #[inline(always)]
+    fn needs_layout(&self) -> bool {
+        self.0.get().is_none()
+    }
+
+    #[inline]
+    fn update_layout(&self, size: Size, _bounds: Bounds) {
+        self.0.set(size).expect("size set twice")
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/mod.rs.html b/src/composable/views/mod.rs.html new file mode 100644 index 00000000..0b9b779a --- /dev/null +++ b/src/composable/views/mod.rs.html @@ -0,0 +1,439 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+
use std::ops::Deref;
+
+pub use lyon::math::{Box2D as Bounds, Point, Size, Transform};
+
+pub use layout::Spacer;
+pub use modifiers::fixed::{Fixed, FixedHeight, FixedWidth};
+pub use modifiers::padding::Padding;
+pub use output::{gpu, svg, Output};
+pub use shapes::{Circle, ContinuousRoundedRectangle, Ellipse, Rectangle, RoundedRectangle};
+pub use shapes::{Path, Shape};
+#[doc(inline)]
+pub use text::Text;
+
+use crate::{From, TryInto};
+
+/// Alias for `euclid::default::SideOffsets2D<f32>`
+pub type Offsets = lyon::geom::euclid::default::SideOffsets2D<f32>;
+
+mod output;
+/// Text handling for `View` construction.
+pub mod text;
+
+pub mod gesture;
+mod layout;
+mod modifiers;
+
+mod shapes;
+#[cfg(feature = "default_ui")]
+pub mod ui;
+
+/// User interface element and modifiers to re-configure it.
+pub trait View: Sized {
+    /// The intrinsic size of the `View`
+    fn size(&self) -> Size;
+    /// User-interface [`Event`] handling of the `View`
+    #[allow(unused_variables)]
+    fn event(&self, event: Event, offset: Point, bounds: Bounds) {}
+    /// How the `View` is drawn
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output);
+
+    /// Add padding to all sides of the `View`
+    fn padding(self, top: f32, right: f32, bottom: f32, left: f32) -> Padding<Self> {
+        Padding {
+            offsets: Offsets::new(top, right, bottom, left),
+            view: self,
+        }
+    }
+
+    /// Add padding to the top of the `View`
+    fn padding_top(self, pad: f32) -> Padding<Self> {
+        self.padding(pad, 0.0, 0.0, 0.0)
+    }
+
+    /// Add padding to the right side of the `View`
+    fn padding_right(self, pad: f32) -> Padding<Self> {
+        self.padding(0.0, pad, 0.0, 0.0)
+    }
+
+    /// Add padding to the bottom of the `View`
+    fn padding_bottom(self, pad: f32) -> Padding<Self> {
+        self.padding(0.0, 0.0, pad, 0.0)
+    }
+
+    /// Add padding to the left side of the `View`
+    fn padding_left(self, pad: f32) -> Padding<Self> {
+        self.padding(0.0, 0.0, 0.0, pad)
+    }
+
+    /// Add padding to the horizontal sides of the `View`
+    fn padding_horizontal(self, pad: f32) -> Padding<Self> {
+        self.padding(0.0, pad, 0.0, pad)
+    }
+
+    /// Add padding to the vertical sides of the `View`
+    fn padding_vertical(self, pad: f32) -> Padding<Self> {
+        self.padding(0.0, 0.0, pad, 0.0)
+    }
+
+    /// Add different padding to the horizontal and vertical sides of the `View`
+    fn padding_both(self, horizontal: f32, vertical: f32) -> Padding<Self> {
+        self.padding(vertical, horizontal, vertical, horizontal)
+    }
+
+    /// Add the same padding to all sides of the `View`
+    fn padding_all(self, pad: f32) -> Padding<Self> {
+        self.padding(pad, pad, pad, pad)
+    }
+
+    /// Set the size of the `View` to a fixed value.
+    fn fixed(self, width: f32, height: f32) -> impl View {
+        let size = self.size();
+        if size.is_empty() {
+            return Err(Fixed {
+                size: Size::new(width, height),
+                view: self,
+            });
+        }
+
+        let horizontal = (width - size.width) / 2.0;
+        let vertical = (height - size.height) / 2.0;
+        Ok(self.padding_both(horizontal, vertical))
+    }
+
+    fn width(self, width: f32) -> impl View {
+        let size = self.size();
+        if size.is_empty() {
+            return Err(FixedWidth { width, view: self });
+        }
+
+        let horizontal = (width - size.width) / 2.0;
+        Ok(self.padding_horizontal(horizontal))
+    }
+
+    fn height(self, height: f32) -> impl View {
+        let size = self.size();
+        if size.is_empty() {
+            return Err(FixedHeight { height, view: self });
+        }
+
+        let vertical = (height - size.height) / 2.0;
+        Ok(self.padding_vertical(vertical))
+    }
+
+    #[doc(hidden)]
+    #[inline(always)]
+    fn needs_layout(&self) -> bool {
+        false
+    }
+
+    #[doc(hidden)]
+    #[inline(always)]
+    fn update_layout(&self, _size: Size, _bounds: Bounds) {}
+
+    /// Causes a tuple of `View`s to cascade horizontally, rather than vertically.
+    /// ## Note
+    /// For other views, nothing changes
+    fn across(self) -> impl View {
+        self
+    }
+}
+
+impl<T: View> View for Box<T> {
+    #[inline(always)]
+    fn size(&self) -> Size {
+        self.deref().size()
+    }
+
+    #[inline(always)]
+    fn event(&self, event: Event, offset: Point, bounds: Bounds) {
+        self.deref().event(event, offset, bounds)
+    }
+
+    #[inline(always)]
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {
+        self.deref().draw(bounds, onto)
+    }
+}
+
+impl<T: View> View for Option<T> {
+    fn size(&self) -> Size {
+        if let Some(view) = self {
+            return view.size();
+        }
+
+        Size::zero()
+    }
+
+    fn event(&self, event: Event, offset: Point, bounds: Bounds) {
+        if let Some(view) = self {
+            view.event(event, offset, bounds)
+        }
+    }
+
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {
+        if let Some(view) = self {
+            view.draw(bounds, onto)
+        }
+    }
+}
+
+impl<T: View, E: View> View for Result<T, E> {
+    fn size(&self) -> Size {
+        match self {
+            Ok(view) => view.size(),
+            Err(view) => view.size(),
+        }
+    }
+
+    fn event(&self, event: Event, offset: Point, bounds: Bounds) {
+        match self {
+            Ok(view) => view.event(event, offset, bounds),
+            Err(view) => view.event(event, offset, bounds),
+        }
+    }
+
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {
+        match self {
+            Ok(view) => view.draw(bounds, onto),
+            Err(view) => view.draw(bounds, onto),
+        }
+    }
+}
+
+/// [`View`] events.
+#[allow(missing_docs)]
+#[derive(Copy, Clone, From, TryInto)]
+pub enum Event {
+    Gesture(Gesture),
+    Resize { width: u32, height: u32 },
+    Redraw,
+}
+
+/// touches… buttons…
+#[derive(Copy, Clone)]
+pub enum Gesture {
+    Began { n: u8 },
+    Moved { n: u8 },
+    Ended { n: u8 },
+}
+
\ No newline at end of file diff --git a/src/composable/views/modifiers/fixed.rs.html b/src/composable/views/modifiers/fixed.rs.html new file mode 100644 index 00000000..a533e5d9 --- /dev/null +++ b/src/composable/views/modifiers/fixed.rs.html @@ -0,0 +1,189 @@ +fixed.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+
use crate::views::{Bounds, Event, Output, Point, Size, View};
+
+///
+pub struct Fixed<V> {
+    pub(crate) view: V,
+    pub(crate) size: Size,
+}
+
+impl<V: View> View for Fixed<V> {
+    #[inline(always)]
+    fn size(&self) -> Size {
+        self.size
+    }
+
+    #[inline]
+    fn event(&self, event: Event, offset: Point, mut bounds: Bounds) {
+        bounds.set_size(self.size);
+        self.view.event(event, offset, bounds)
+    }
+
+    #[inline]
+    fn draw(&self, mut bounds: Bounds, onto: &mut impl Output) {
+        bounds.set_size(self.size);
+        self.view.draw(bounds, onto)
+    }
+}
+
+///
+pub struct FixedWidth<V: View> {
+    pub(crate) view: V,
+    pub(crate) width: f32,
+}
+
+impl<V: View> View for FixedWidth<V> {
+    #[inline]
+    fn size(&self) -> Size {
+        let mut size = self.view.size();
+        size.width = self.width;
+
+        size
+    }
+
+    #[inline]
+    fn event(&self, event: Event, offset: Point, mut bounds: Bounds) {
+        let mut size = bounds.size();
+        size.width = self.width;
+        bounds.set_size(size);
+
+        self.view.event(event, offset, bounds)
+    }
+
+    #[inline]
+    fn draw(&self, mut bounds: Bounds, onto: &mut impl Output) {
+        let mut size = bounds.size();
+        size.width = self.width;
+        bounds.set_size(size);
+
+        self.view.draw(bounds, onto)
+    }
+}
+
+///
+pub struct FixedHeight<V: View> {
+    pub(crate) view: V,
+    pub(crate) height: f32,
+}
+
+impl<V: View> View for FixedHeight<V> {
+    #[inline]
+    fn size(&self) -> Size {
+        let mut size = self.view.size();
+        size.height = self.height;
+
+        size
+    }
+
+    #[inline]
+    fn event(&self, event: Event, offset: Point, mut bounds: Bounds) {
+        let mut size = bounds.size();
+        size.height = self.height;
+        bounds.set_size(size);
+
+        self.view.event(event, offset, bounds)
+    }
+
+    #[inline]
+    fn draw(&self, mut bounds: Bounds, onto: &mut impl Output) {
+        let mut size = bounds.size();
+        size.height = self.height;
+        bounds.set_size(size);
+
+        self.view.draw(bounds, onto)
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/modifiers/mod.rs.html b/src/composable/views/modifiers/mod.rs.html new file mode 100644 index 00000000..54ec906f --- /dev/null +++ b/src/composable/views/modifiers/mod.rs.html @@ -0,0 +1,7 @@ +mod.rs - source
1
+2
+3
+
pub mod fixed;
+pub mod offset;
+pub mod padding;
+
\ No newline at end of file diff --git a/src/composable/views/modifiers/offset.rs.html b/src/composable/views/modifiers/offset.rs.html new file mode 100644 index 00000000..75de6f0a --- /dev/null +++ b/src/composable/views/modifiers/offset.rs.html @@ -0,0 +1,51 @@ +offset.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+
use crate::views::{Bounds, Event, Output, Point, Size, View};
+
+pub struct Offset<V> {
+    pub(crate) view: V,
+    pub(crate) offsets: Point,
+}
+
+impl<V: View> View for Offset<V> {
+    #[inline(always)]
+    fn size(&self) -> Size {
+        self.view.size()
+    }
+
+    #[inline]
+    fn event(&self, event: Event, offset: Point, mut bounds: Bounds) {
+        bounds.min += self.offsets.to_vector();
+        self.view.event(event, offset, bounds)
+    }
+
+    #[inline]
+    fn draw(&self, mut bounds: Bounds, onto: &mut impl Output) {
+        bounds.min += self.offsets.to_vector();
+        self.view.draw(bounds, onto)
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/modifiers/padding.rs.html b/src/composable/views/modifiers/padding.rs.html new file mode 100644 index 00000000..26e168f5 --- /dev/null +++ b/src/composable/views/modifiers/padding.rs.html @@ -0,0 +1,55 @@ +padding.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+
use crate::views::{Bounds, Event, Offsets, Output, Point, Size, View};
+
+pub struct Padding<V> {
+    pub(crate) view: V,
+    pub(crate) offsets: Offsets,
+}
+
+impl<V: View> View for Padding<V> {
+    #[inline]
+    fn size(&self) -> Size {
+        let mut size = self.view.size();
+        size.width += self.offsets.horizontal();
+        size.height += self.offsets.vertical();
+
+        size
+    }
+
+    #[inline(always)]
+    fn event(&self, event: Event, offset: Point, bounds: Bounds) {
+        self.view.event(event, offset, bounds)
+    }
+
+    #[inline]
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {
+        self.view.draw(bounds.inner_box(self.offsets), onto)
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/output/gpu.rs.html b/src/composable/views/output/gpu.rs.html new file mode 100644 index 00000000..847807a1 --- /dev/null +++ b/src/composable/views/output/gpu.rs.html @@ -0,0 +1,281 @@ +gpu.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+
//! GPU [`Output`] for `Views`
+use lyon::path::builder::{NoAttributes, Transformed};
+use lyon::path::{BuilderImpl as Builder, Path};
+use lyon::tessellation::{
+    FillGeometryBuilder, FillOptions, FillTessellator, FillVertex, GeometryBuilder,
+    GeometryBuilderError, VertexId,
+};
+
+use crate::views::Transform;
+
+///  
+pub struct Output {
+    storage: Storage,
+    options: FillOptions,
+    builder: NoAttributes<Transformed<Builder, Transform>>,
+}
+
+impl Output {
+    /// Creates an indexed-triangle data `Output`.
+    pub fn new(rounding: f32) -> Self {
+        let builder = Self::builder();
+        let storage = Storage::default();
+
+        let options = FillOptions::non_zero().with_tolerance(if rounding > 0.0 {
+            rounding
+        } else {
+            FillOptions::DEFAULT_TOLERANCE
+        });
+
+        Self {
+            storage,
+            options,
+            builder,
+        }
+    }
+
+    /// Consumes the `Output` and returns the constructed indexed-triangle data.
+    /// - vertices are stored as (x, y, rgba) tuples
+    /// - indices are stored as 32-bit offsets
+    ///
+    /// ## Example
+    /// A WGSL shader that consumes this `Output`’s output:
+    ///
+    /// ```wgsl
+    #[doc = include_str!("../../../examples/winit/wgpu/shader.wgsl")]
+    /// ```
+    #[allow(clippy::type_complexity)]
+    pub fn into_inner(mut self) -> (Vec<(i16, i16, [u8; 4])>, Vec<u32>) {
+        self.tessellate();
+        self.storage.into_inner()
+    }
+
+    #[inline(never)]
+    fn tessellate(&mut self) {
+        let builder = std::mem::replace(&mut self.builder, Self::builder());
+
+        let path = builder.build();
+        let mut tessellator = FillTessellator::default();
+        tessellator
+            .tessellate_path(&path, &self.options, &mut self.storage)
+            .expect("tessellate_path");
+    }
+
+    fn builder() -> NoAttributes<Transformed<Builder, Transform>> {
+        Path::builder().transformed(Default::default())
+    }
+}
+
+impl super::Output for Output {
+    #[inline]
+    fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform) {
+        if rgba != self.storage.rgba {
+            self.tessellate();
+        }
+
+        self.storage.rgba = rgba;
+        self.builder.inner_mut().set_transform(*transform);
+
+        self.builder.begin((x, y).into());
+    }
+
+    #[inline]
+    fn line_to(&mut self, x: f32, y: f32) {
+        self.builder.line_to((x, y).into());
+    }
+
+    #[inline]
+    fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
+        self.builder
+            .quadratic_bezier_to((x1, y1).into(), (x, y).into());
+    }
+
+    #[inline]
+    fn cubic_bezier_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
+        self.builder
+            .cubic_bezier_to((x1, y1).into(), (x2, y2).into(), (x, y).into());
+    }
+
+    #[inline]
+    fn close(&mut self) {
+        self.builder.close();
+    }
+}
+
+///
+#[derive(Default)]
+struct Storage {
+    vertices: Vec<(i16, i16, [u8; 4])>,
+    indices: Vec<u32>,
+    rgba: [u8; 4],
+}
+
+impl Storage {
+    #[allow(clippy::type_complexity)]
+    pub fn into_inner(self) -> (Vec<(i16, i16, [u8; 4])>, Vec<u32>) {
+        eprintln!("{} vertices", self.vertices.len());
+        (self.vertices, self.indices)
+    }
+}
+
+#[doc(hidden)]
+impl FillGeometryBuilder for Storage {
+    #[inline]
+    fn add_fill_vertex(&mut self, vertex: FillVertex) -> Result<VertexId, GeometryBuilderError> {
+        let id = self.vertices.len() as u32;
+        let (x, y) = vertex.position().into();
+
+        self.vertices.push((x as i16, y as i16, self.rgba));
+        Ok(id.into())
+    }
+}
+
+#[doc(hidden)]
+impl GeometryBuilder for Storage {
+    #[inline]
+    fn add_triangle(&mut self, a: VertexId, b: VertexId, c: VertexId) {
+        let triangle: [u32; 3] = [a, b, c].map(|id| id.into());
+        self.indices.extend_from_slice(&triangle);
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/output/mod.rs.html b/src/composable/views/output/mod.rs.html new file mode 100644 index 00000000..9d7c65dd --- /dev/null +++ b/src/composable/views/output/mod.rs.html @@ -0,0 +1,83 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
#![allow(clippy::too_many_arguments)]
+//! The end result of view drawing.
+//!
+//! [`View`]: super::View
+
+use crate::views::Transform;
+
+pub mod gpu;
+pub mod svg;
+
+/// A surface, or file format, that views may be rendered to.
+#[rustfmt::skip]
+pub trait Output: Sized {
+    /// Begins a new path.
+    ///
+    /// The path should be continued with a series of [`line_to`], [`quadratic_bezier_to`], and/or
+    /// [`cubic_bezier_to`] calls and ended with a call to [`close`].
+    ///
+    /// [`line_to`]: Self::line_to
+    /// [`quadratic_bezier_to`]: Self::quadratic_bezier_to
+    /// [`cubic_bezier_to`]: Self::cubic_bezier_to
+    /// [`close`]: Self::close
+    fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform);
+    /// Adds a line to the current path.
+    fn line_to(&mut self, x: f32, y: f32);
+    /// Adds a quadratic Bézier to the current path.
+    ///
+    /// (`x1`, `y1`) represents the Bézier control point.
+    fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32);
+    /// Adds a cubic Bézier to the current path.
+    ///
+    /// (`x1`, `y1`) and (`x2`, `y2`) represent the Bézier control points.
+    fn cubic_bezier_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32);
+
+    /// Closes the current path.
+    ///
+    /// Once this method has been called there is no current path until [`begin`] is called again.
+    ///
+    /// [`begin`]: Self::begin
+    fn close(&mut self);
+}
+
\ No newline at end of file diff --git a/src/composable/views/output/svg.rs.html b/src/composable/views/output/svg.rs.html new file mode 100644 index 00000000..a6438964 --- /dev/null +++ b/src/composable/views/output/svg.rs.html @@ -0,0 +1,189 @@ +svg.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+
//! SVG [`Output`] for `Views`
+
+use svg::node::element::path::{Command, Position};
+use svg::{node::element::path::Data, node::element::Path, Document, Node};
+
+use crate::views::Transform;
+
+///
+pub struct Output {
+    svg: Document,
+    transform: Transform,
+    data: Data,
+    rgba: [u8; 4],
+}
+
+impl Output {
+    /// Creates a Scalable Vector Graphics `Output`.
+    pub fn new(width: f32, height: f32) -> Self {
+        Self {
+            svg: Document::new()
+                .set("viewBox", (0, 0, width, height))
+                .set("width", width)
+                .set("height", height),
+            transform: Default::default(),
+            data: Default::default(),
+            rgba: [0; 4],
+        }
+    }
+
+    fn end_current_node(&mut self) {
+        let data = std::mem::take(&mut self.data);
+
+        let fill = format!(
+            "#{:02x}{:02x}{:02x}{:02x}",
+            self.rgba[0], self.rgba[1], self.rgba[2], self.rgba[3]
+        );
+
+        let array = self.transform.to_array();
+        let transform = format!(
+            "matrix({} {} {} {} {} {})",
+            array[0], array[1], array[2], array[3], array[4], array[5]
+        );
+
+        self.svg.append(
+            Path::new()
+                .set("transform", transform)
+                .set("fill", fill)
+                .set("d", data),
+        );
+    }
+
+    /// Consumes the `Output` and returns the constructed SVG string.
+    pub fn into_inner(mut self) -> String {
+        self.end_current_node();
+        self.svg.to_string()
+    }
+}
+
+impl super::Output for Output {
+    fn begin(&mut self, x: f32, y: f32, rgba: [u8; 4], transform: &Transform) {
+        if !self.data.is_empty() && (rgba != self.rgba || !transform.approx_eq(&self.transform)) {
+            self.end_current_node();
+        }
+
+        self.rgba = rgba;
+        self.transform = *transform;
+
+        self.data
+            .append(Command::Move(Position::Absolute, (x, y).into()));
+    }
+
+    fn line_to(&mut self, x: f32, y: f32) {
+        self.data
+            .append(Command::Line(Position::Absolute, (x, y).into()));
+    }
+
+    fn quadratic_bezier_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
+        self.data.append(Command::QuadraticCurve(
+            Position::Absolute,
+            (x1, y1, x, y).into(),
+        ));
+    }
+
+    fn cubic_bezier_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
+        self.data.append(Command::CubicCurve(
+            Position::Absolute,
+            (x1, y1, x2, y2, x, y).into(),
+        ));
+    }
+
+    fn close(&mut self) {
+        self.data.append(Command::Close);
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/shapes/mod.rs.html b/src/composable/views/shapes/mod.rs.html new file mode 100644 index 00000000..cb15b0e5 --- /dev/null +++ b/src/composable/views/shapes/mod.rs.html @@ -0,0 +1,335 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+
use crate::dependencies::Dependency;
+use crate::views::{Bounds, Output, Size, Transform, View};
+
+mod rounded;
+
+pub trait Path: Sized {
+    fn draw(&self, x: f32, y: f32, w: f32, h: f32, transform: &Transform, onto: &mut impl Output);
+
+    fn fill(self) -> Shape<Self> {
+        self.fixed(f32::INFINITY, f32::INFINITY)
+    }
+
+    fn fixed(self, width: f32, height: f32) -> Shape<Self> {
+        Shape {
+            size: Size::new(width, height),
+            path: self,
+        }
+    }
+}
+
+/// [Least-squares approximation of the circle using cubic Bézier curves][site]
+///
+/// > David Ellsworth found the optimal value of c:  
+/// >
+/// > c ≈ 0.5519703814011128603134107
+///
+/// [site]: https://spencermortensen.com/articles/least-squares-bezier-circle/
+pub(crate) const K: f32 = 0.4480296; // 1 - 0.5519703814011128603134107 rounded to f32
+
+pub struct Rectangle {
+    pub rgba: [u8; 4],
+}
+
+impl Path for Rectangle {
+    #[inline(always)]
+    fn draw(&self, x: f32, y: f32, w: f32, h: f32, transform: &Transform, onto: &mut impl Output) {
+        rounded::rectangle(x, y, w, h, 0.0, 0.0, 0.0, self.rgba, transform, onto);
+    }
+}
+
+impl Rectangle {
+    pub fn rounded(self, rx: f32, ry: f32) -> RoundedRectangle {
+        RoundedRectangle {
+            rgba: self.rgba,
+            rx,
+            ry,
+        }
+    }
+}
+
+pub struct RoundedRectangle {
+    rgba: [u8; 4],
+    rx: f32,
+    ry: f32,
+}
+
+impl Path for RoundedRectangle {
+    #[inline(always)]
+    fn draw(&self, x: f32, y: f32, w: f32, h: f32, transform: &Transform, onto: &mut impl Output) {
+        rounded::rectangle(x, y, w, h, self.rx, self.ry, K, self.rgba, transform, onto);
+    }
+}
+
+impl RoundedRectangle {
+    pub fn continuous(self) -> ContinuousRoundedRectangle {
+        ContinuousRoundedRectangle {
+            rgba: self.rgba,
+            rx: self.rx,
+            ry: self.ry,
+        }
+    }
+}
+
+pub struct ContinuousRoundedRectangle {
+    rgba: [u8; 4],
+    rx: f32,
+    ry: f32,
+}
+
+impl Path for ContinuousRoundedRectangle {
+    #[inline(always)]
+    fn draw(&self, x: f32, y: f32, w: f32, h: f32, transform: &Transform, onto: &mut impl Output) {
+        // continuous corners are much smaller than circular ones; scale them up a bit
+        let c = std::f32::consts::E;
+        let rx = (self.rx * c).min(w / 2.0);
+        let ry = (self.ry * c).min(h / 2.0);
+        rounded::rectangle(x, y, w, h, rx, ry, 0.0, self.rgba, transform, onto);
+    }
+}
+
+pub struct Ellipse {
+    pub rgba: [u8; 4],
+}
+
+impl Path for Ellipse {
+    #[inline(always)]
+    fn draw(&self, x: f32, y: f32, w: f32, h: f32, transform: &Transform, onto: &mut impl Output) {
+        let rx = w / 2.0;
+        let ry = h / 2.0;
+        rounded::rectangle(x, y, w, h, rx, ry, K, self.rgba, transform, onto);
+    }
+}
+
+pub struct Circle {
+    pub rgba: [u8; 4],
+}
+
+impl Path for Circle {
+    #[inline(always)]
+    fn draw(&self, x: f32, y: f32, w: f32, h: f32, transform: &Transform, onto: &mut impl Output) {
+        let r = f32::min(w, h) / 2.0;
+        rounded::rectangle(x, y, w, h, r, r, K, self.rgba, transform, onto);
+    }
+}
+
+#[doc(hidden)]
+pub struct Shape<T> {
+    size: Size,
+    path: T,
+}
+
+impl<T: Path> View for Shape<T> {
+    #[inline(always)]
+    fn size(&self) -> Size {
+        self.size
+    }
+
+    #[inline]
+    fn draw(&self, bounds: Bounds, onto: &mut impl Output) {
+        let size = match (self.size.width.is_finite(), self.size.height.is_finite()) {
+            (true, true) => self.size,
+            (false, false) => bounds.size(),
+            (true, false) => Size::new(self.size.width, bounds.height()),
+            (false, true) => Size::new(bounds.width(), self.size.height),
+        };
+
+        self.path.draw(
+            bounds.min.x,
+            bounds.min.y,
+            size.width,
+            size.height,
+            &Dependency::<Transform>::new().unwrap_or_default(),
+            onto,
+        );
+    }
+
+    #[inline(always)]
+    #[allow(refining_impl_trait)]
+    fn fixed(mut self, width: f32, height: f32) -> Self {
+        self.size = Size::new(width, height);
+        self
+    }
+
+    #[inline(always)]
+    #[allow(refining_impl_trait)]
+    fn width(mut self, width: f32) -> Self {
+        self.size.width = width;
+        self
+    }
+
+    #[inline(always)]
+    #[allow(refining_impl_trait)]
+    fn height(mut self, height: f32) -> Self {
+        self.size.height = height;
+        self
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/shapes/rounded.rs.html b/src/composable/views/shapes/rounded.rs.html new file mode 100644 index 00000000..daace5a8 --- /dev/null +++ b/src/composable/views/shapes/rounded.rs.html @@ -0,0 +1,161 @@ +rounded.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+
use crate::views::{Output, Transform};
+
+#[inline(never)]
+#[allow(clippy::too_many_arguments)]
+pub(crate) fn rectangle(
+    x: f32,
+    y: f32,
+    w: f32,
+    h: f32,
+    rx: f32,
+    ry: f32,
+    k: f32,
+    rgba: [u8; 4],
+    transform: &Transform,
+    output: &mut impl Output,
+) {
+    let p0 = (x, y + ry);
+    let c0 = (x, y + ry * k);
+    let c1 = (x + rx * k, y);
+    let p1 = (x + rx, y);
+
+    let p2 = (x + w - rx, y);
+    let c2 = (x + w - rx * k, y);
+    let c3 = (x + w, y + ry * k);
+    let p3 = (x + w, y + ry);
+
+    let p4 = (x + w, y + h - ry);
+    let c4 = (x + w, y + h - ry * k);
+    let c5 = (x + w - rx * k, y + h);
+    let p5 = (x + w - rx, y + h);
+
+    let p6 = (x + rx, y + h);
+    let c6 = (x + rx * k, y + h);
+    let c7 = (x, y + h - ry * k);
+    let p7 = (x, y + h - ry);
+
+    output.begin(p0.0, p0.1, rgba, transform);
+    output.cubic_bezier_to(c0.0, c0.1, c1.0, c1.1, p1.0, p1.1);
+    output.line_to(p2.0, p2.1);
+    output.cubic_bezier_to(c2.0, c2.1, c3.0, c3.1, p3.0, p3.1);
+    output.line_to(p4.0, p4.1);
+    output.cubic_bezier_to(c4.0, c4.1, c5.0, c5.1, p5.0, p5.1);
+    output.line_to(p6.0, p6.1);
+    output.cubic_bezier_to(c6.0, c6.1, c7.0, c7.1, p7.0, p7.1);
+    output.close();
+}
+
+#[test]
+fn snapshot_testing() {
+    use super::Path;
+    use insta::assert_snapshot;
+
+    let black = [0, 0, 0, 0xff];
+    let transform = Default::default();
+
+    let mut output = crate::views::svg::Output::new(256.0, 256.0);
+    let circle = super::Circle { rgba: black };
+    circle.draw(16.0, 16.0, 224.0, 224.0, &transform, &mut output);
+    assert_snapshot!("circle", output.into_inner());
+
+    let mut output = crate::views::svg::Output::new(256.0, 128.0);
+    let ellipse = super::Ellipse { rgba: black };
+    ellipse.draw(16.0, 16.0, 224.0, 112.0, &transform, &mut output);
+    assert_snapshot!("ellipse", output.into_inner());
+
+    let mut output = crate::views::svg::Output::new(256.0, 128.0);
+    let rectangle = super::Rectangle { rgba: black };
+    rectangle.draw(16.0, 16.0, 224.0, 112.0, &transform, &mut output);
+    assert_snapshot!("rectangle", output.into_inner());
+
+    let mut output = crate::views::svg::Output::new(256.0, 128.0);
+    let rounded = rectangle.rounded(16.0, 16.0);
+    rounded.draw(16.0, 16.0, 224.0, 112.0, &transform, &mut output);
+    assert_snapshot!("rounded", output.into_inner());
+
+    let mut output = crate::views::svg::Output::new(256.0, 128.0);
+    let continuous = rounded.continuous();
+    continuous.draw(16.0, 16.0, 224.0, 112.0, &transform, &mut output);
+    assert_snapshot!("continuous", output.into_inner());
+}
+
\ No newline at end of file diff --git a/src/composable/views/text/font.rs.html b/src/composable/views/text/font.rs.html new file mode 100644 index 00000000..2576744b --- /dev/null +++ b/src/composable/views/text/font.rs.html @@ -0,0 +1,499 @@ +font.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+
use rustybuzz::ttf_parser::name_id::{FAMILY, FULL_NAME, SUBFAMILY, UNIQUE_ID, VERSION};
+use rustybuzz::ttf_parser::{GlyphId, OutlineBuilder, Tag};
+use rustybuzz::{shape_with_plan, Face, ShapePlan, UnicodeBuffer};
+pub use rustybuzz::{Direction, Feature, GlyphBuffer as Glyphs, Language, Script};
+
+use crate::views::Text;
+
+///
+pub struct Font<'a> {
+    face: Face<'a>,
+    plan: ShapePlan,
+    size: f32,
+}
+
+impl<'a> Font<'a> {
+    /// Full font name that reflects all family and relevant subfamily descriptors.
+    #[inline]
+    pub fn full_name(&self) -> Option<String> {
+        self.name(FULL_NAME)
+    }
+
+    /// Family name.
+    #[inline]
+    pub fn family(&self) -> Option<String> {
+        self.name(FAMILY)
+    }
+
+    /// Subfamily name.
+    #[inline]
+    pub fn style(&self) -> Option<String> {
+        self.name(SUBFAMILY)
+    }
+
+    /// Unique font identifier
+    #[inline]
+    pub fn identifier(&self) -> Option<String> {
+        self.name(UNIQUE_ID)
+    }
+
+    /// Should begin with the syntax “Version _N_._M_”
+    /// (upper case, lower case, or mixed, with a space between “Version” and the number).
+    #[inline]
+    pub fn version(&self) -> Option<String> {
+        self.name(VERSION)
+    }
+
+    #[inline(never)]
+    fn name(&self, id: u16) -> Option<String> {
+        self.face
+            .names()
+            .into_iter()
+            .find(|name| name.name_id == id)
+            .and_then(|name| name.to_string())
+    }
+
+    /// Font size in points.
+    #[inline]
+    pub fn size(&self) -> f32 {
+        self.size
+    }
+
+    /// Horizontal face ascender.
+    pub fn ascender(&self) -> f32 {
+        self.face.ascender() as f32
+    }
+
+    /// Horizontal face descender,
+    pub fn descender(&self) -> f32 {
+        self.face.descender() as f32
+    }
+
+    /// Horizontal height,
+    #[inline]
+    pub fn height(&self) -> f32 {
+        self.face.height() as f32
+    }
+
+    /// Capital height,
+    #[inline]
+    pub fn capital_height(&self) -> f32 {
+        self.face
+            .capital_height()
+            .unwrap_or_else(|| self.face.ascender()) as f32
+    }
+
+    /// Line gap,
+    #[inline]
+    pub fn line_gap(&self) -> f32 {
+        self.face.line_gap() as f32
+    }
+
+    /// Returns a `Text` in this font.
+    #[inline(never)]
+    pub fn text(&self, rgba: [u8; 4], string: &str) -> Text {
+        let mut unicode = UnicodeBuffer::new();
+        unicode.push_str(string);
+
+        let glyphs = shape_with_plan(&self.face, &self.plan, unicode);
+        let scale = self.size / self.face.units_per_em() as f32;
+
+        // TODO: both of these assume Direction::LeftToRight or RightToLeft
+        let width = glyphs
+            .glyph_positions()
+            .iter()
+            .fold(0.0, |width, position| {
+                width + (position.x_offset + position.x_advance) as f32
+            })
+            * scale;
+
+        Text {
+            font: self,
+            glyphs,
+            width,
+            scale,
+            rgba,
+        }
+    }
+
+    #[inline(always)]
+    pub(crate) fn outline_glyph(&self, glyph: u32, builder: &mut impl OutlineBuilder) {
+        self.face.outline_glyph(GlyphId(glyph as u16), builder);
+    }
+}
+
+impl<'a> Font<'a> {
+    /// Create a `Font` from the raw font data.
+    #[inline(always)]
+    pub fn from(data: &'a [u8]) -> Option<FontConfig> {
+        Self::from_collection(data, 0)
+    }
+
+    /// Create a `Font` from a font collection.
+    /// Returns the font at `index`, if any
+    #[inline(never)]
+    pub fn from_collection(data: &'a [u8], index: u32) -> Option<FontConfig> {
+        let face = Face::from_slice(data, index)?;
+
+        Some(FontConfig {
+            face,
+            features: Vec::default(),
+            direction: None,
+            script: None,
+            language: None,
+            weight: None,
+        })
+    }
+}
+
+///
+#[derive(Clone)]
+pub struct FontConfig<'a> {
+    face: Face<'a>,
+    features: Vec<Feature>,
+    direction: Option<Direction>,
+    script: Option<Script>,
+    language: Option<Language>,
+    weight: Option<f32>,
+}
+
+impl<'a> FontConfig<'a> {
+    ///
+    #[inline]
+    pub fn direction(self, direction: Direction) -> Self {
+        Self {
+            direction: Some(direction),
+            ..self
+        }
+    }
+
+    ///
+    #[inline]
+    pub fn script(self, script: Script) -> Self {
+        Self {
+            script: Some(script),
+            ..self
+        }
+    }
+
+    ///
+    #[inline]
+    pub fn language(self, language: Language) -> Self {
+        Self {
+            language: Some(language),
+            ..self
+        }
+    }
+
+    ///
+    #[inline]
+    pub fn feature(mut self, tag: &[u8; 4], value: u32) -> Self {
+        self.features
+            .push(Feature::new(Tag::from_bytes(tag), value, ..));
+
+        self
+    }
+
+    ///
+    #[inline]
+    pub fn weight(self, weight: f32) -> Self {
+        Self {
+            weight: Some(weight),
+            ..self
+        }
+    }
+
+    /// The final step in building a Font.
+    #[inline(never)]
+    pub fn size(mut self, size: f32) -> Font<'a> {
+        for axis in self.face.variation_axes().into_iter() {
+            match &axis.tag.to_bytes() {
+                b"opsz" => {
+                    let opsz = size.clamp(axis.min_value, axis.max_value);
+                    self.face.set_variation(axis.tag, opsz);
+                }
+                b"wght" => {
+                    let wght = self
+                        .weight
+                        .map(|w| w.clamp(axis.min_value, axis.max_value))
+                        .unwrap_or(axis.def_value);
+
+                    self.face.set_variation(axis.tag, wght);
+                }
+                _ => {}
+            }
+        }
+
+        // Using direction.unwrap_or_default() would give an Direction::Invalid
+        // and that will panic!() in ShapePlan::new()
+        let direction = self.direction.unwrap_or(Direction::LeftToRight);
+
+        let script = self
+            .script
+            .or_else(|| Script::from_iso15924_tag(Tag::from_bytes(b"Latn")));
+
+        let plan = ShapePlan::new(
+            &self.face,
+            direction,
+            script,
+            self.language.as_ref(),
+            &self.features,
+        );
+
+        Font {
+            face: self.face,
+            plan,
+            size,
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/text/mod.rs.html b/src/composable/views/text/mod.rs.html new file mode 100644 index 00000000..9abf8569 --- /dev/null +++ b/src/composable/views/text/mod.rs.html @@ -0,0 +1,223 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+
pub use font::{Direction, Font, FontConfig, Glyphs, Language, Script};
+
+use crate::dependencies::Dependency;
+use crate::views::{Bounds, Output, Size, Transform, View};
+
+mod font;
+
+/// Text data
+#[doc(hidden)] // documented as views::Text
+pub struct Text<'a> {
+    font: &'a Font<'a>,
+    glyphs: Glyphs,
+    width: f32,
+    scale: f32,
+    rgba: [u8; 4],
+}
+
+impl Text<'_> {
+    /// Height of the Text’s font.
+    #[inline]
+    pub fn height(&self) -> f32 {
+        self.font.height() * self.scale
+    }
+
+    /// Ascender height of the Text’s font.
+    #[inline]
+    pub fn ascender(&self) -> f32 {
+        self.font.ascender() * self.scale
+    }
+
+    /// Descender height of the Text’s font.  
+    /// Note that this is a negative value.
+    #[inline]
+    pub fn descender(&self) -> f32 {
+        self.font.descender() * self.scale
+    }
+
+    /// Capital height of the Text’s font.
+    #[inline]
+    pub fn capital_height(&self) -> f32 {
+        self.font.capital_height() * self.scale
+    }
+
+    /// Line gap of the Text’s font.
+    #[inline]
+    pub fn line_gap(&self) -> f32 {
+        self.font.line_gap() * self.scale
+    }
+}
+
+impl View for Text<'_> {
+    #[inline(always)]
+    fn size(&self) -> Size {
+        (self.width, self.height()).into()
+    }
+
+    fn draw(&self, bounds: Bounds, output: &mut impl Output) {
+        struct Builder<'a, T: Output> {
+            transform: Transform,
+            output: &'a mut T,
+            rgba: [u8; 4],
+        }
+
+        impl<'a, F: Output> rustybuzz::ttf_parser::OutlineBuilder for Builder<'a, F> {
+            fn move_to(&mut self, x: f32, y: f32) {
+                self.output.begin(x, y, self.rgba, &self.transform);
+            }
+
+            fn line_to(&mut self, x: f32, y: f32) {
+                self.output.line_to(x, y);
+            }
+
+            fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
+                self.output.quadratic_bezier_to(x1, y1, x, y);
+            }
+
+            fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
+                self.output.cubic_bezier_to(x1, y1, x2, y2, x, y);
+            }
+
+            fn close(&mut self) {
+                self.output.close();
+            }
+        }
+
+        let transform = Dependency::<Transform>::new();
+        let mut builder = Builder {
+            transform: Transform::scale(self.scale, -self.scale) // negate y-axis
+                .then_translate((0.0, self.ascender()).into()) // font baseline
+                .then_translate(bounds.min.to_vector()) // start position,
+                .then(&transform.unwrap_or_default()),
+            rgba: self.rgba,
+            output,
+        };
+
+        let positions = self.glyphs.glyph_positions().iter();
+        let glyphs = self.glyphs.glyph_infos().iter();
+
+        for (glyph, position) in Iterator::zip(glyphs, positions) {
+            builder.transform = builder
+                .transform // “How much the glyph moves on the [X/Y]-axis before drawing it”
+                .pre_translate((position.x_offset as f32, position.y_offset as f32).into());
+
+            self.font.outline_glyph(glyph.glyph_id, &mut builder);
+
+            builder.transform = builder
+                .transform // “How much the line advances after drawing this glyph”
+                .pre_translate((position.x_advance as f32, position.y_advance as f32).into());
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/accessibility.rs.html b/src/composable/views/ui/accessibility.rs.html new file mode 100644 index 00000000..ac6545f0 --- /dev/null +++ b/src/composable/views/ui/accessibility.rs.html @@ -0,0 +1,73 @@ +accessibility.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+
use crate::dependencies::DependencyDefault;
+
+/// `Scale` defines a predefined scale for scalable content.
+#[derive(Copy, Clone)]
+pub enum Scale {
+    /// Use extra extra small sizes.  
+    /// This is the default on desktop platforms.
+    XXS,
+    /// use extra small sizes.
+    XS,
+    /// Use small sizes.
+    S,
+    /// Use medium sizes.
+    M,
+    /// Use large sizes.  
+    /// This is the default on mobile platforms.
+    L,
+    /// use extra large sizes.
+    XL,
+    /// Use extra extra large sizes.
+    XXL,
+    /// Use extra extra extra large sizes.
+    XXXL,
+}
+
+impl Default for Scale {
+    fn default() -> Self {
+        if cfg!(target_os = "ios") || cfg!(target_os = "android") {
+            Scale::L
+        } else {
+            Scale::XXS
+        }
+    }
+}
+
+impl DependencyDefault for Scale {}
+
\ No newline at end of file diff --git a/src/composable/views/ui/colors/gray.rs.html b/src/composable/views/ui/colors/gray.rs.html new file mode 100644 index 00000000..2c65dfab --- /dev/null +++ b/src/composable/views/ui/colors/gray.rs.html @@ -0,0 +1,153 @@ +gray.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+
//! Shades of gray; where
+//!
+//! - zero is black,
+//! - sixteen is white, with
+//! - fifteen shades of gray in between.
+
+const fn shifted(grey: u8, by: u8) -> [u8; 4] {
+    let blue = grey.saturating_add(by);
+    [grey, grey, blue, 0xff]
+}
+
+/// Color progression is based upon a smoothed (reciprocal) decibel scale.
+///
+/// | n    | dB      | hex  | dec  |
+/// | ---- | ------- | ---- | ---- |
+/// | 0    | 1.00    | 0x00 | 0    |
+/// | 1    | 0.80    | 0x33 | 51   |
+/// | 2    | 0.66667 | 0x55 | 85   |
+/// | 3    | 0.50    | 0x80 | 128  |
+/// | 4    | 0.40    | 0x99 | 153  |
+/// | 5    | 0.33333 | 0xAA | 170  |
+/// | 6    | 0.25    | 0xBF | 191  |
+/// | 7    | 0.20    | 0xCC | 204  |
+/// | 8    | 0.16667 | 0xD5 | 213  |
+/// | 9    | 0.125   | 0xDF | 223  |
+/// | 10   | 0.10    | 0xE6 | 230  |
+/// | 11   | 0.08333 | 0xEA | 234  |
+/// | 12   | 0.0625  | 0xEF | 239  |
+/// | 13   | 0.05    | 0xF2 | 242  |
+/// | 14   | 0.04167 | 0xF4 | 244  |
+/// | 15   | 0.03125 | 0xF7 | 247  |
+const fn decibel(n: u8) -> u8 {
+    debug_assert!(n <= 16);
+
+    // we oversize the constant array because `let n = n.clamp(0, 16);` gives us:
+    //
+    //     error[E0015]: cannot call non-const fn `<u8 as Ord>::clamp` in constant functions
+    //
+    const GRAY: [u8; 256] = [
+        0x00, // 255 - (10^(-n ÷ 10) × 255)
+        0x33, 0x55, 0x80, 0x99, 0xaa, 0xbf, 0xcc, 0xd5, 0xdf, 0xe6, 0xea, 0xef, 0xf2, 0xf4, 0xf7,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+        0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    ];
+
+    GRAY[n as usize]
+}
+
+/// Gray wih a noticable blue tint
+pub const fn background(brightness: u8) -> [u8; 4] {
+    shifted(decibel(brightness), 5)
+}
+
+/// Gray with a subtle blue tint
+pub const fn foreground(brightness: u8) -> [u8; 4] {
+    shifted(decibel(brightness), 2)
+}
+
+/// Gray with no tint; pure grays
+pub const fn pure(brightness: u8) -> [u8; 4] {
+    shifted(decibel(brightness), 0)
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/colors/mod.rs.html b/src/composable/views/ui/colors/mod.rs.html new file mode 100644 index 00000000..326e58cf --- /dev/null +++ b/src/composable/views/ui/colors/mod.rs.html @@ -0,0 +1,107 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+
use theme::Theme;
+
+mod theme;
+
+pub mod gray;
+
+pub fn primary_content() -> [u8; 4] {
+    theme::current().primary_content()
+}
+
+pub fn secondary_content() -> [u8; 4] {
+    theme::current().secondary_content()
+}
+
+pub fn tertiary_content() -> [u8; 4] {
+    theme::current().tertiary_content()
+}
+
+pub fn quaternary_content() -> [u8; 4] {
+    theme::current().quaternary_content()
+}
+
+pub fn primary_shapes() -> [u8; 4] {
+    theme::current().primary_shapes()
+}
+
+pub fn secondary_shapes() -> [u8; 4] {
+    theme::current().secondary_shapes()
+}
+
+pub fn tertiary_shapes() -> [u8; 4] {
+    theme::current().tertiary_shapes()
+}
+
+pub fn quaternary_shapes() -> [u8; 4] {
+    theme::current().quaternary_shapes()
+}
+
+pub fn primary_background() -> [u8; 4] {
+    theme::current().primary_background()
+}
+
+pub fn secondary_background() -> [u8; 4] {
+    theme::current().secondary_background()
+}
+
+pub fn tertiary_background() -> [u8; 4] {
+    theme::current().tertiary_background()
+}
+
+pub fn quaternary_background() -> [u8; 4] {
+    theme::current().quaternary_background()
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/colors/theme.rs.html b/src/composable/views/ui/colors/theme.rs.html new file mode 100644 index 00000000..198508f9 --- /dev/null +++ b/src/composable/views/ui/colors/theme.rs.html @@ -0,0 +1,275 @@ +theme.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+
use crate::dependencies::{Dependency, DependencyDefault};
+
+use super::gray;
+
+pub struct Current(Box<dyn Theme>);
+
+impl Default for Current {
+    fn default() -> Self {
+        Current(Box::new(Light))
+    }
+}
+
+pub fn current() -> Dependency<Current> {
+    Dependency::<Current>::new()
+}
+
+impl Theme for Current {
+    fn primary_content(&self) -> [u8; 4] {
+        self.0.primary_content()
+    }
+
+    fn secondary_content(&self) -> [u8; 4] {
+        self.0.secondary_content()
+    }
+
+    fn tertiary_content(&self) -> [u8; 4] {
+        self.0.tertiary_content()
+    }
+
+    fn quaternary_content(&self) -> [u8; 4] {
+        self.0.quaternary_content()
+    }
+
+    fn primary_shapes(&self) -> [u8; 4] {
+        self.0.primary_shapes()
+    }
+
+    fn secondary_shapes(&self) -> [u8; 4] {
+        self.0.secondary_shapes()
+    }
+
+    fn tertiary_shapes(&self) -> [u8; 4] {
+        self.0.tertiary_shapes()
+    }
+
+    fn quaternary_shapes(&self) -> [u8; 4] {
+        self.0.quaternary_shapes()
+    }
+
+    fn primary_background(&self) -> [u8; 4] {
+        self.0.primary_background()
+    }
+
+    fn secondary_background(&self) -> [u8; 4] {
+        self.0.secondary_background()
+    }
+
+    fn tertiary_background(&self) -> [u8; 4] {
+        self.0.tertiary_background()
+    }
+
+    fn quaternary_background(&self) -> [u8; 4] {
+        self.0.quaternary_background()
+    }
+}
+
+impl DependencyDefault for Current {}
+
+pub trait Theme {
+    fn primary_content(&self) -> [u8; 4];
+    fn secondary_content(&self) -> [u8; 4];
+    fn tertiary_content(&self) -> [u8; 4];
+    fn quaternary_content(&self) -> [u8; 4];
+
+    fn primary_shapes(&self) -> [u8; 4];
+    fn secondary_shapes(&self) -> [u8; 4];
+    fn tertiary_shapes(&self) -> [u8; 4];
+    fn quaternary_shapes(&self) -> [u8; 4];
+
+    fn primary_background(&self) -> [u8; 4];
+    fn secondary_background(&self) -> [u8; 4];
+    fn tertiary_background(&self) -> [u8; 4];
+    fn quaternary_background(&self) -> [u8; 4];
+}
+
+struct Light;
+struct Dark;
+
+impl Theme for Light {
+    fn primary_content(&self) -> [u8; 4] {
+        gray::pure(0)
+    }
+
+    fn secondary_content(&self) -> [u8; 4] {
+        gray::foreground(3)
+    }
+
+    fn tertiary_content(&self) -> [u8; 4] {
+        gray::foreground(6)
+    }
+
+    fn quaternary_content(&self) -> [u8; 4] {
+        gray::foreground(9)
+    }
+
+    fn primary_shapes(&self) -> [u8; 4] {
+        gray::foreground(10)
+    }
+
+    fn secondary_shapes(&self) -> [u8; 4] {
+        gray::foreground(11)
+    }
+
+    fn tertiary_shapes(&self) -> [u8; 4] {
+        gray::foreground(12)
+    }
+
+    fn quaternary_shapes(&self) -> [u8; 4] {
+        gray::foreground(14) // progression break…
+    }
+
+    fn primary_background(&self) -> [u8; 4] {
+        gray::background(14)
+    }
+
+    fn secondary_background(&self) -> [u8; 4] {
+        gray::background(12)
+    }
+
+    fn tertiary_background(&self) -> [u8; 4] {
+        gray::background(10)
+    }
+
+    fn quaternary_background(&self) -> [u8; 4] {
+        gray::background(8)
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/font/mod.rs.html b/src/composable/views/ui/font/mod.rs.html new file mode 100644 index 00000000..fe077e68 --- /dev/null +++ b/src/composable/views/ui/font/mod.rs.html @@ -0,0 +1,193 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+
//! Minimal `Font` handling.
+
+use std::marker::PhantomData;
+use std::ops::Deref;
+
+use crate::dependencies::{with_dependencies, with_dependency};
+pub use typography::{body, label, title};
+
+use crate::views::text::Font;
+use crate::views::ui::accessibility::Scale;
+
+mod typography;
+
+/// The [Inter font](https://github.com/rsms/inter/blob/master/README.md)
+///
+/// > # Inter
+/// >
+/// > Inter is a typeface carefully crafted & designed for computer screens.
+/// > Inter features a tall x-height to aid in readability of mixed-case and
+/// > lower-case text.
+/// > Inter is a [variable font](https://rsms.me/inter/#variable) with
+/// > several [OpenType features](https://rsms.me/inter/#features),
+/// > like contextual alternates that adjusts punctuation depending on the shape
+/// > of surrounding glyphs, slashed zero for when you need to disambiguate
+/// > "0" from "o", tabular numbers, etc.
+/// >  
+/// > <br>
+/// >
+/// > ![Sample](https://github.com/rsms/inter/raw/master/misc/readme/intro.png)
+///
+/// [Release 4.0](https://github.com/rsms/inter/releases/tag/v4.0)
+pub struct Inter<'a, Style> {
+    marker: PhantomData<Style>,
+    font: Font<'a>,
+}
+
+impl<'a, Style> Deref for Inter<'a, Style> {
+    type Target = Font<'a>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.font
+    }
+}
+
+/// Sets the default font for the supplied closure.
+pub fn with_default_fonts<F: FnOnce() -> R, R>(f: F) -> R {
+    with_dependency(Scale::default(), || {
+        with_dependencies(
+            (
+                Inter::<body::L>::default(),
+                Inter::<body::M>::default(),
+                Inter::<body::S>::default(),
+                Inter::<title::L>::default(),
+                Inter::<title::M>::default(),
+                Inter::<title::S>::default(),
+                Inter::<label::L>::default(),
+                Inter::<label::M>::default(),
+                Inter::<label::S>::default(),
+            ),
+            f,
+        )
+    })
+}
+
+#[test]
+fn test_font_defaults() {
+    use crate::dependencies::Dependency;
+
+    with_default_fonts(|| {
+        let body = Dependency::<Inter<body::M>>::new();
+        assert!(body.is_some());
+    });
+}
+
+#[test]
+fn snapshot_testing() {
+    use crate::dependencies::Dependency;
+    use crate::views::{svg::Output as Svg, Bounds, View};
+    use insta::assert_snapshot;
+
+    with_default_fonts(|| {
+        let black = [0, 0, 0, 0xff];
+        let body = Dependency::<Inter<body::M>>::new();
+        let caption = Dependency::<Inter<body::S>>::new();
+
+        let text = (
+            body.text(black, "This space intentionally left blank."),
+            caption.text(black, "except for this, I mean…"),
+        );
+        let size = text.size().ceil();
+
+        let mut output = Svg::new(size.width, size.height);
+        text.draw(Bounds::from_size(size), &mut output);
+        assert_snapshot!("body text", output.into_inner());
+    });
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/font/typography/mod.rs.html b/src/composable/views/ui/font/typography/mod.rs.html new file mode 100644 index 00000000..9176709c --- /dev/null +++ b/src/composable/views/ui/font/typography/mod.rs.html @@ -0,0 +1,255 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+
#![allow(dead_code)]
+
+use std::marker::PhantomData;
+
+use crate::dependencies::{Dependency, DependencyDefault};
+use crate::views::text::Font;
+use crate::views::ui::{accessibility, Inter};
+
+mod scale;
+
+#[allow(non_upper_case_globals)]
+const InterVariable: &[u8] = include_bytes!("../InterVariable.ttf");
+
+#[inline(never)]
+fn font<Design>(weight: f32, scale: f32) -> Inter<'static, Design> {
+    let accessibility = Dependency::<accessibility::Scale>::new();
+
+    Inter {
+        marker: PhantomData,
+        font: Font::from(InterVariable)
+            .unwrap()
+            .weight(weight)
+            .size(accessibility.scale(scale)),
+    }
+}
+
+/// Title `Font` styles.
+pub mod title {
+    use super::*;
+
+    /// Large variant
+    pub struct L;
+    /// Medium variant
+    pub struct M;
+    /// Small variant
+    pub struct S;
+
+    impl DependencyDefault for Inter<'static, L> {}
+    impl DependencyDefault for Inter<'static, M> {}
+    impl DependencyDefault for Inter<'static, S> {}
+
+    impl Default for Inter<'static, L> {
+        fn default() -> Self {
+            font(650.0, 6.0)
+        }
+    }
+
+    impl Default for Inter<'static, M> {
+        fn default() -> Self {
+            font(650.0, 4.0)
+        }
+    }
+
+    impl Default for Inter<'static, S> {
+        fn default() -> Self {
+            font(650.0, 3.0)
+        }
+    }
+}
+
+/// Body `Font` styles.
+pub mod body {
+    use super::*;
+
+    /// Large variant
+    pub struct L;
+    /// Medium variant
+    pub struct M;
+    /// Small variant
+    pub struct S;
+
+    impl DependencyDefault for Inter<'static, L> {}
+    impl DependencyDefault for Inter<'static, M> {}
+    impl DependencyDefault for Inter<'static, S> {}
+
+    impl Default for Inter<'static, L> {
+        fn default() -> Self {
+            font(500.0, 4.0)
+        }
+    }
+
+    impl Default for Inter<'static, M> {
+        fn default() -> Self {
+            font(500.0, 3.0)
+        }
+    }
+
+    impl Default for Inter<'static, S> {
+        fn default() -> Self {
+            font(400.0, 2.0)
+        }
+    }
+}
+
+/// Label `Font` styles.
+pub mod label {
+    use super::*;
+
+    /// Large variant
+    pub struct L;
+    /// Medium variant
+    pub struct M;
+    /// Small variant
+    pub struct S;
+
+    impl DependencyDefault for Inter<'static, L> {}
+    impl DependencyDefault for Inter<'static, M> {}
+    impl DependencyDefault for Inter<'static, S> {}
+
+    impl Default for Inter<'static, L> {
+        fn default() -> Self {
+            font(600.0, 2.0)
+        }
+    }
+
+    impl Default for Inter<'static, M> {
+        fn default() -> Self {
+            font(600.0, 1.0)
+        }
+    }
+
+    impl Default for Inter<'static, S> {
+        fn default() -> Self {
+            font(400.0, 0.0)
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/font/typography/scale.rs.html b/src/composable/views/ui/font/typography/scale.rs.html new file mode 100644 index 00000000..1e45c23d --- /dev/null +++ b/src/composable/views/ui/font/typography/scale.rs.html @@ -0,0 +1,147 @@ +scale.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+
use crate::views::ui::accessibility::Scale;
+
+fn size_xxxl(i: f32) -> f32 {
+    size_xxl(i) + 2.0
+}
+
+fn size_xxl(i: f32) -> f32 {
+    size_xl(i) + 2.0
+}
+
+fn size_xl(i: f32) -> f32 {
+    size_l(i) + 2.0
+}
+
+fn size_l(i: f32) -> f32 {
+    size_m(i)
+        + match i {
+            i if i < 0.5 => 0.0,
+            i if i < 6.5 => 1.0,
+            _ => 2.0,
+        }
+}
+
+fn size_m(i: f32) -> f32 {
+    size_s(i)
+        + match i {
+            i if i < 6.5 => 1.0,
+            _ => 2.0,
+        }
+}
+
+fn size_s(i: f32) -> f32 {
+    size_xs(i)
+        + match i {
+            i if i < 0.5 => 0.0,
+            i if i < 6.5 => 1.0,
+            _ => 2.0,
+        }
+}
+
+fn size_xs(i: f32) -> f32 {
+    size_xxs(i)
+        + match i {
+            i if i < 6.5 => 1.0,
+            _ => 2.0,
+        }
+}
+
+fn size_xxs(i: f32) -> f32 {
+    // fi = f₀ × r^(i/n)
+    let r = 1.618034f32; // Φ
+    let n = 5.0f32;
+    let f = 10.0f32;
+
+    (f * r.powf(i / n)).round().max(10.0)
+}
+
+impl Scale {
+    /// `Font` scale per `Accessibility` level
+    #[inline(never)]
+    pub fn scale(&self, i: f32) -> f32 {
+        match self {
+            Scale::XXS => size_xxs(i),
+            Scale::XS => size_xs(i),
+            Scale::S => size_s(i),
+            Scale::M => size_m(i),
+            Scale::L => size_l(i),
+            Scale::XL => size_xl(i),
+            Scale::XXL => size_xxl(i),
+            Scale::XXXL => size_xxxl(i),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/composable/views/ui/mod.rs.html b/src/composable/views/ui/mod.rs.html new file mode 100644 index 00000000..5752733e --- /dev/null +++ b/src/composable/views/ui/mod.rs.html @@ -0,0 +1,59 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+
//! A minimal, _but viable_, user interface layer.
+//!
+//! # Minimal
+//!
+//! **Minimal** exist as a separate feature so that applications that need
+//! completely custom user interface elements are not weighted down by the
+//! implementations here; while still having access to those same interface
+//! elements to use as reference when building their own.
+//!
+//! - **Configurable**  
+//!   Much of the design of Minimal’s user interface elements has been
+//!   configured via `dependencies` as default values. As such they can be
+//!   overridden by the applications as needed.
+//! - **Incremental**  
+//!   Furthermore, use of Minimal does not need to be all or nothing.
+//!   Development of an application can begin with Minimal’s default
+//!   look-and-feel and custom `View` implementations can be added
+//!   incrementally to the application as its configurability becomes
+//!   insufficient.
+
+pub use font::{with_default_fonts, Inter};
+
+pub mod accessibility;
+pub mod colors;
+pub mod font;
+pub mod spacer;
+
+#[doc(inline)]
+pub use spacer::spacing;
+
\ No newline at end of file diff --git a/src/composable/views/ui/spacer.rs.html b/src/composable/views/ui/spacer.rs.html new file mode 100644 index 00000000..99ee07cd --- /dev/null +++ b/src/composable/views/ui/spacer.rs.html @@ -0,0 +1,241 @@ +spacer.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+
#![allow(non_snake_case)]
+use crate::views::Spacer;
+
+pub mod spacing {
+    /// The amount of space taken up by a [`spacer::XXS()`]
+    ///
+    /// [`spacer::XXS()`]: super::XXS
+    pub const XXS: f32 = 2.0;
+
+    /// The amount of space taken up by a [`spacer::XS()`]
+    ///
+    /// [`spacer::XS()`]: super::XS
+    pub const XS: f32 = 4.0;
+
+    /// The amount of space taken up by a [`spacer::S()`]
+    ///
+    /// [`spacer::S()`]: super::S
+    pub const S: f32 = 8.0;
+
+    /// The amount of space taken up by a [`spacer::M()`]
+    /// - A good minimum target size for trackpads/mice
+    ///
+    /// [`spacer::M()`]: super::M
+    pub const M: f32 = 18.0; // tableview row height (after the dividing line)
+
+    /// The amount of space taken up by a [`spacer::L()`]
+    /// - A good minimum target height for “[a sentence or block of text][WCAG]”
+    ///
+    /// [`spacer::L()`]: super::L
+    /// [WCAG]: https://www.smashingmagazine.com/2023/04/accessible-tap-target-sizes-rage-taps-clicks/#not-all-pixels-are-the-same
+    pub const L: f32 = 28.0;
+
+    /// The amount of space taken up by a [`spacer::XL()`]
+    ///
+    /// [`spacer::XL()`]: super::XL
+    pub const XL: f32 = 38.0; // medium toolbar height (before the dividing line)
+
+    /// The amount of space taken up by a [`spacer::XXL()`]
+    /// - A good minimum target size for tablets/phones/touchscreen
+    ///
+    /// [`spacer::XXL()`]: super::XXL
+    pub const XXL: f32 = 48.0; // phone tab bar height (before the (invisible) dividing line)
+
+    /// The amount of space taken up by a [`spacer::XXXL()`]
+    // - A good minimum target size for VR elements
+    ///
+    /// [`spacer::XXXL()`]: super::XXXL
+    pub const XXXL: f32 = 58.0;
+}
+
+#[inline(always)]
+pub fn fill() -> Spacer {
+    Spacer::fill()
+}
+
+#[inline(always)]
+pub fn fixed(width: f32, height: f32) -> Spacer {
+    Spacer::fixed(width, height)
+}
+
+#[inline(always)]
+pub fn width(width: f32) -> Spacer {
+    Spacer::width(width)
+}
+
+#[inline(always)]
+pub fn height(height: f32) -> Spacer {
+    Spacer::height(height)
+}
+
+#[inline(always)]
+pub fn empty() -> Spacer {
+    Spacer::empty()
+}
+
+#[inline(always)]
+#[allow(clippy::should_implement_trait)]
+pub fn default() -> Spacer {
+    S()
+}
+
+#[inline(always)]
+pub fn XXS() -> Spacer {
+    fixed(spacing::XXS, spacing::XXS)
+}
+
+#[inline(always)]
+pub fn XS() -> Spacer {
+    fixed(spacing::XS, spacing::XS)
+}
+
+#[inline(always)]
+pub fn S() -> Spacer {
+    fixed(spacing::S, spacing::S)
+}
+
+#[inline(always)]
+pub fn M() -> Spacer {
+    fixed(spacing::M, spacing::M)
+}
+
+#[inline(always)]
+pub fn L() -> Spacer {
+    fixed(spacing::L, spacing::L)
+}
+
+#[inline(always)]
+pub fn XL() -> Spacer {
+    fixed(spacing::XL, spacing::XL)
+}
+
+#[inline(always)]
+pub fn XXL() -> Spacer {
+    fixed(spacing::XXL, spacing::XXL)
+}
+
+#[inline(always)]
+pub fn XXXL() -> Spacer {
+    fixed(spacing::XXXL, spacing::XXXL)
+}
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 00000000..1447df79 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 00000000..d7e9c149 --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 00000000..7a1e5fc5 Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 00000000..e766e06c Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 00000000..1866ad4b Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 00000000..4b3edc29 --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 00000000..462c34ef Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 00000000..0d2941e1 --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 00000000..10b558e0 Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 00000000..5ec64eef Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 00000000..181a07f6 Binary files /dev/null and b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 00000000..2ae08a7b Binary files /dev/null and b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 00000000..175fa4f4 --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 00000000..0263fc30 Binary files /dev/null and b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 00000000..8b34b511 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 00000000..69b8613c Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/main-20a3ad099b048cf2.js b/static.files/main-20a3ad099b048cf2.js new file mode 100644 index 00000000..133116e4 --- /dev/null +++ b/static.files/main-20a3ad099b048cf2.js @@ -0,0 +1,11 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function blurHandler(event,parentElem,hideCallback){if(!parentElem.contains(document.activeElement)&&!parentElem.contains(event.relatedTarget)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.querySelector(".rustdoc"),"crate")){mobileTitle.innerHTML=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url,errorCallback){const script=document.createElement("script");script.src=url;if(errorCallback!==undefined){script.onerror=errorCallback}document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=").map(x=>x.replace(/\+/g," "));params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function sendSearchForm(){document.getElementsByClassName("search-form")[0].submit()}function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"),sendSearchForm);loadScript(resourcePath("search-index",".js"),sendSearchForm)}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},descShards:new Map(),loadDesc:async function({descShard,descIndex}){if(descShard.promise===null){descShard.promise=new Promise((resolve,reject)=>{descShard.resolve=resolve;const ds=descShard;const fname=`${ds.crate}-desc-${ds.shard}-`;const url=resourcePath(`search.desc/${descShard.crate}/${fname}`,".js",);loadScript(url,reject)})}const list=await descShard.promise;return list[descIndex]},loadedDescShard:function(crate,shard,data){this.descShards.get(crate)[shard].resolve(data.split("\n"))},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}},)}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":case"/":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.querySelector(".rustdoc"),"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","),);for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";link.textContent=crate;const li=document.createElement("li");if(window.rootPath!=="./"&&crate===window.currentCrate){li.className="current"}li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px",)}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!e.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S / /","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){const SIDEBAR_MIN=100;const SIDEBAR_MAX=500;const RUSTDOC_MOBILE_BREAKPOINT=700;const BODY_MIN=400;const SIDEBAR_VANISH_THRESHOLD=SIDEBAR_MIN/2;const sidebarButton=document.getElementById("sidebar-button");if(sidebarButton){sidebarButton.addEventListener("click",e=>{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false");if(document.querySelector(".rustdoc.src")){window.rustdocToggleSrcSidebar()}e.preventDefault()})}let currentPointerId=null;let desiredSidebarSize=null;let pendingSidebarResizingFrame=false;const resizer=document.querySelector(".sidebar-resizer");const sidebar=document.querySelector(".sidebar");if(!resizer||!sidebar){return}const isSrcPage=hasClass(document.body,"src");function hideSidebar(){if(isSrcPage){window.rustdocCloseSourceSidebar();updateLocalStorage("src-sidebar-width",null);document.documentElement.style.removeProperty("--src-sidebar-width");sidebar.style.removeProperty("--src-sidebar-width");resizer.style.removeProperty("--src-sidebar-width")}else{addClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","true");updateLocalStorage("desktop-sidebar-width",null);document.documentElement.style.removeProperty("--desktop-sidebar-width");sidebar.style.removeProperty("--desktop-sidebar-width");resizer.style.removeProperty("--desktop-sidebar-width")}}function showSidebar(){if(isSrcPage){window.rustdocShowSourceSidebar()}else{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false")}}function changeSidebarSize(size){if(isSrcPage){updateLocalStorage("src-sidebar-width",size);sidebar.style.setProperty("--src-sidebar-width",size+"px");resizer.style.setProperty("--src-sidebar-width",size+"px")}else{updateLocalStorage("desktop-sidebar-width",size);sidebar.style.setProperty("--desktop-sidebar-width",size+"px");resizer.style.setProperty("--desktop-sidebar-width",size+"px")}}function isSidebarHidden(){return isSrcPage?!hasClass(document.documentElement,"src-sidebar-expanded"):hasClass(document.documentElement,"hide-sidebar")}function resize(e){if(currentPointerId===null||currentPointerId!==e.pointerId){return}e.preventDefault();const pos=e.clientX-3;if(pos=SIDEBAR_MIN){if(isSidebarHidden()){showSidebar()}const constrainedPos=Math.min(pos,window.innerWidth-BODY_MIN,SIDEBAR_MAX);changeSidebarSize(constrainedPos);desiredSidebarSize=constrainedPos;if(pendingSidebarResizingFrame!==false){clearTimeout(pendingSidebarResizingFrame)}pendingSidebarResizingFrame=setTimeout(()=>{if(currentPointerId===null||pendingSidebarResizingFrame===false){return}pendingSidebarResizingFrame=false;document.documentElement.style.setProperty("--resizing-sidebar-width",desiredSidebarSize+"px",)},100)}}window.addEventListener("resize",()=>{if(window.innerWidth=(window.innerWidth-BODY_MIN)){changeSidebarSize(window.innerWidth-BODY_MIN)}else if(desiredSidebarSize!==null&&desiredSidebarSize>SIDEBAR_MIN){changeSidebarSize(desiredSidebarSize)}});function stopResize(e){if(currentPointerId===null){return}if(e){e.preventDefault()}desiredSidebarSize=sidebar.getBoundingClientRect().width;removeClass(resizer,"active");window.removeEventListener("pointermove",resize,false);window.removeEventListener("pointerup",stopResize,false);removeClass(document.documentElement,"sidebar-resizing");document.documentElement.style.removeProperty("--resizing-sidebar-width");if(resizer.releasePointerCapture){resizer.releasePointerCapture(currentPointerId);currentPointerId=null}}function initResize(e){if(currentPointerId!==null||e.altKey||e.ctrlKey||e.metaKey||e.button!==0){return}if(resizer.setPointerCapture){resizer.setPointerCapture(e.pointerId);if(!resizer.hasPointerCapture(e.pointerId)){resizer.releasePointerCapture(e.pointerId);return}currentPointerId=e.pointerId}window.hideAllModals(false);e.preventDefault();window.addEventListener("pointermove",resize,false);window.addEventListener("pointercancel",stopResize,false);window.addEventListener("pointerup",stopResize,false);addClass(resizer,"active");addClass(document.documentElement,"sidebar-resizing");const pos=e.clientX-sidebar.offsetLeft-3;document.documentElement.style.setProperty("--resizing-sidebar-width",pos+"px");desiredSidebarSize=null}resizer.addEventListener("pointerdown",initResize,false)}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.classList.add("clicked");if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){reset_button_timeout=null;but.classList.remove("clicked")}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 00000000..469959f1 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-df360f571f6edeae.css b/static.files/noscript-df360f571f6edeae.css new file mode 100644 index 00000000..4c310ae5 --- /dev/null +++ b/static.files/noscript-df360f571f6edeae.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path,#sidebar-button,.sidebar-resizer{display:none !important;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root,:root:not([data-theme]){--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--settings-menu-filter:none;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}@media (prefers-color-scheme:dark){:root,:root:not([data-theme]){--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 00000000..62424d8f --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-dd39b87e5fcfba68.css b/static.files/rustdoc-dd39b87e5fcfba68.css new file mode 100644 index 00000000..77f89832 --- /dev/null +++ b/static.files/rustdoc-dd39b87e5fcfba68.css @@ -0,0 +1,46 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;--desktop-sidebar-width:200px;--src-sidebar-width:300px;--desktop-sidebar-z-index:100;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.logo-container{line-height:0;display:block;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 var(--desktop-sidebar-width);width:var(--desktop-sidebar-width);overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;z-index:var(--desktop-sidebar-z-index);}.rustdoc.src .sidebar{flex-basis:50px;width:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.hide-sidebar .sidebar,.hide-sidebar .sidebar-resizer{display:none;}.sidebar-resizer{touch-action:none;width:9px;cursor:col-resize;z-index:calc(var(--desktop-sidebar-z-index) + 1);position:fixed;height:100%;left:calc(var(--desktop-sidebar-width) + 1px);}.rustdoc.src .sidebar-resizer{left:49px;}.src-sidebar-expanded .src .sidebar-resizer{left:var(--src-sidebar-width);}.sidebar-resizing{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.sidebar-resizing*{cursor:col-resize !important;}.sidebar-resizing .sidebar{position:fixed;}.sidebar-resizing>body{padding-left:var(--resizing-sidebar-width);}.sidebar-resizer:hover,.sidebar-resizer:active,.sidebar-resizer:focus,.sidebar-resizer.active{width:10px;margin:0;left:var(--desktop-sidebar-width);border-left:solid 1px var(--sidebar-resizer-hover);}.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active{left:calc(var(--src-sidebar-width) - 1px);}@media (pointer:coarse){.sidebar-resizer{display:none !important;}}.sidebar-resizer.active{padding:0 140px;width:2px;margin-left:-140px;border-left:none;}.sidebar-resizer.active:before{border-left:solid 2px var(--sidebar-resizer-active);display:block;height:100%;content:"";}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}.src .sidebar>*{visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:var(--src-sidebar-width);width:var(--src-sidebar-width);}.src-sidebar-expanded .src .sidebar>*{visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;margin-right:0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.2rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.2rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}div.where{white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.section-header{display:block;position:relative;}.section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.section-header>.anchor{left:-15px;padding-right:8px;}h2.section-header>.anchor{padding-right:6px;}a.doc-anchor{color:var(--main-color);display:none;position:absolute;left:-17px;padding-right:5px;padding-left:3px;}*:hover>.doc-anchor{display:block;}.top-doc>.docblock>*:first-child>.doc-anchor{display:none !important;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover:not(.doc-anchor),.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block li.current a{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:calc(var(--desktop-sidebar-z-index) + 1);margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{display:block;padding:3px;margin-bottom:5px;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;vertical-align:baseline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji,.item-info .stab::before{font-size:1.25rem;}.stab .emoji{margin-right:0.3rem;}.item-info .stab::before{content:"\0";width:0;display:inline-block;color:transparent;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}.top-doc>.docblock>.warning:first-child::before{top:20px;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}.src-sidebar-title{position:sticky;top:0;display:flex;padding:8px 8px 0 48px;margin-bottom:7px;background:var(--sidebar-background-color);border-bottom:1px solid var(--border-color);}#settings-menu,#help-button{margin-left:4px;display:flex;}#sidebar-button{display:none;line-height:0;}.hide-sidebar #sidebar-button,.src #sidebar-button{display:flex;margin-right:4px;position:fixed;left:6px;height:34px;width:34px;background-color:var(--main-background-color);z-index:1;}.src #sidebar-button{left:8px;z-index:calc(var(--desktop-sidebar-z-index) + 1);}.hide-sidebar .src #sidebar-button{position:static;}#settings-menu>a,#help-button>a,#sidebar-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus,#sidebar-button>a:hover,#sidebar-button>a:focus{border-color:var(--settings-button-border-focus);}#settings-menu>a{line-height:0;font-size:0;}#settings-menu>a:before{content:url('data:image/svg+xml,\ + ');width:22px;height:22px;filter:var(--settings-menu-filter);}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;width:33px;margin-left:10px;padding:0;padding-left:2px;border:0;font-size:0;}#copy-path::before{filter:var(--copy-path-img-filter);content:url('data:image/svg+xml,\ +\ +\ +');width:19px;height:18px;}#copy-path:hover::before{filter:var(--copy-path-img-hover-filter);}#copy-path.clicked::before{content:url('data:image/svg+xml,\ + \ + ');}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}.src #sidebar-button>a:before,.sidebar-menu-toggle:before{content:url('data:image/svg+xml,\ + ');opacity:0.75;}.sidebar-menu-toggle:hover:before,.sidebar-menu-toggle:active:before,.sidebar-menu-toggle:focus:before{opacity:1;}.src #sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');opacity:0.75;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location,.sidebar-resizer{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.src .search-form{margin-left:40px;}.hide-sidebar .search-form{margin-left:32px;}.hide-sidebar .src .search-form{margin-left:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;white-space:nowrap;text-overflow:ellipsis;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.hide-sidebar .mobile-topbar{display:none;}.sidebar-menu-toggle{width:45px;border:none;line-height:0;}.hide-sidebar .sidebar-menu-toggle{display:none;}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#copy-path,#help-button{display:none;}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}.sidebar-menu-toggle:before{filter:var(--mobile-sidebar-menu-filter);}.sidebar-menu-toggle:hover{background:var(--main-background-color);}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{position:fixed;max-width:100vw;width:100vw;}.src .src-sidebar-title{padding-top:0;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"],:root:not([data-theme]){--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--settings-menu-filter:none;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--settings-menu-filter:none;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--settings-menu-filter:invert(100%);--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);--sidebar-resizer-hover:hsl(34,50%,33%);--sidebar-resizer-active:hsl(34,100%,66%);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar .current a,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img,:root[data-theme="ayu"] #sidebar-button>a:before{filter:invert(100);} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 00000000..ba830e37 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-0fe7219eb170c82e.js b/static.files/search-0fe7219eb170c82e.js new file mode 100644 index 00000000..da6b6b96 --- /dev/null +++ b/static.files/search-0fe7219eb170c82e.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["keyword","primitive","mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","associatedtype","constant","associatedconstant","union","foreigntype","existential","attr","derive","traitalias","generic",];const longItemTypes=["keyword","primitive type","module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","assoc type","constant","assoc const","union","foreign type","existential type","attribute macro","derive macro","trait alias",];const TY_GENERIC=itemTypes.indexOf("generic");const TY_IMPORT=itemTypes.indexOf("import");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";const UNBOXING_LIMIT=5;const REGEX_IDENT=/\p{ID_Start}\p{ID_Continue}*|_\p{ID_Continue}+/uy;const REGEX_INVALID_TYPE_FILTER=/[^a-z]/ui;function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost,);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1,)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let searchIndexDeprecated;let searchIndexEmptyDesc;let functionTypeFingerprint;let currentResults;const typeNameIdMap=new Map();const ALIASES=new Map();const typeNameIdOfArray=buildTypeMapIndex("array");const typeNameIdOfSlice=buildTypeMapIndex("slice");const typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");const typeNameIdOfTuple=buildTypeMapIndex("tuple");const typeNameIdOfUnit=buildTypeMapIndex("unit");const typeNameIdOfTupleOrUnit=buildTypeMapIndex("()");const typeNameIdOfFn=buildTypeMapIndex("fn");const typeNameIdOfFnMut=buildTypeMapIndex("fnmut");const typeNameIdOfFnOnce=buildTypeMapIndex("fnonce");const typeNameIdOfHof=buildTypeMapIndex("->");function buildTypeMapIndex(name,isAssocType){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){const obj=typeNameIdMap.get(name);obj.assocOnly=isAssocType&&obj.assocOnly;return obj.id}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,{id,assocOnly:isAssocType});return id}}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return"=,>-])".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function consumeIdent(parserState){REGEX_IDENT.lastIndex=parserState.pos;const match=parserState.userQuery.match(REGEX_IDENT);if(match){parserState.pos+=match[0].length;return true}return false}function isSeparatorCharacter(c){return c===","||c==="="}function isPathSeparator(c){return c===":"||c===" "}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(c!==" "){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}const bindingName=parserState.isInBinding;parserState.isInBinding=null;return makePrimitiveElement("never",{bindingName})}const quadcolon=/::\s*::/.exec(path);if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(quadcolon!==null){throw["Unexpected ",quadcolon[0]]}const pathSegments=path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}const bindingName=parserState.isInBinding;parserState.isInBinding=null;const bindings=new Map();const pathLast=pathSegments[pathSegments.length-1];return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast,normalizedPathLast:pathLast.replace(/_/g,""),generics:generics.filter(gen=>{if(gen.bindingName!==null){if(gen.name!==null){gen.bindingName.generics.unshift(gen)}bindings.set(gen.bindingName.name,gen.bindingName.generics);return false}return true}),bindings,typeFilter,bindingName,}}function getIdentEndPosition(parserState){let afterIdent=consumeIdent(parserState);let end=parserState.pos;let macroExclamation=-1;while(parserState.pos0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]," (not a valid identifier)"]}else{throw["Unexpected ",c," (not a valid identifier)"]}parserState.pos+=1;afterIdent=consumeIdent(parserState);end=parserState.pos}if(macroExclamation!==-1){if(parserState.typeFilter===null){parserState.typeFilter="macro"}else if(parserState.typeFilter!=="macro"){throw["Invalid search type: macro ","!"," and ",parserState.typeFilter," both specified",]}end=macroExclamation}return end}function getFilteredNextElem(query,parserState,elems,isInGenerics){const start=parserState.pos;if(parserState.userQuery[parserState.pos]===":"&&!isPathStart(parserState)){throw["Expected type filter before ",":"]}getNextElem(query,parserState,elems,isInGenerics);if(parserState.userQuery[parserState.pos]===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}if(elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;getNextElem(query,parserState,elems,isInGenerics)}}function getNextElem(query,parserState,elems,isInGenerics){const generics=[];skipWhitespace(parserState);let start=parserState.pos;let end;if("[(".indexOf(parserState.userQuery[parserState.pos])!==-1){let endChar=")";let name="()";let friendlyName="tuple";if(parserState.userQuery[parserState.pos]==="["){endChar="]";name="[]";friendlyName="slice"}parserState.pos+=1;const{foundSeparator}=getItemsBefore(query,parserState,generics,endChar);const typeFilter=parserState.typeFilter;const bindingName=parserState.isInBinding;parserState.typeFilter=null;parserState.isInBinding=null;for(const gen of generics){if(gen.bindingName!==null){throw["Type parameter ","=",` cannot be within ${friendlyName} `,name]}}if(name==="()"&&!foundSeparator&&generics.length===1&&typeFilter===null){elems.push(generics[0])}else if(name==="()"&&generics.length===1&&generics[0].name==="->"){generics[0].typeFilter=typeFilter;elems.push(generics[0])}else{if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive ",name," and ",typeFilter," both specified",]}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}elems.push(makePrimitiveElement(name,{bindingName,generics}))}}else if(parserState.userQuery[parserState.pos]==="&"){if(parserState.typeFilter!==null&&parserState.typeFilter!=="primitive"){throw["Invalid search type: primitive ","&"," and ",parserState.typeFilter," both specified",]}parserState.typeFilter=null;parserState.pos+=1;let c=parserState.userQuery[parserState.pos];while(c===" "&&parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}else if(parserState.pos=end){throw["Found generics without a path"]}if(parserState.isInBinding){throw["Unexpected ","("," after ","="]}parserState.pos+=1;const typeFilter=parserState.typeFilter;parserState.typeFilter=null;getItemsBefore(query,parserState,generics,")");skipWhitespace(parserState);if(isReturnArrow(parserState)){parserState.pos+=2;skipWhitespace(parserState);getFilteredNextElem(query,parserState,generics,isInGenerics);generics[generics.length-1].bindingName=makePrimitiveElement("output")}else{generics.push(makePrimitiveElement(null,{bindingName:makePrimitiveElement("output"),typeFilter:null,}))}parserState.typeFilter=typeFilter}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}if(parserState.userQuery[parserState.pos]==="="){if(parserState.isInBinding){throw["Cannot write ","="," twice in a binding"]}if(!isInGenerics){throw["Type parameter ","="," must be within generics list"]}const name=parserState.userQuery.slice(start,end).trim();if(name==="!"){throw["Type parameter ","="," key cannot be ","!"," never type"]}if(name.includes("!")){throw["Type parameter ","="," key cannot be ","!"," macro"]}if(name.includes("::")){throw["Type parameter ","="," key cannot contain ","::"," path"]}if(name.includes(":")){throw["Type parameter ","="," key cannot contain ",":"," type"]}parserState.isInBinding={name,generics}}else{elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics,),)}}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let foundSeparator=false;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;const oldIsInBinding=parserState.isInBinding;parserState.isInBinding=null;let hofParameters=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===")"){extra="("}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"," after ","="]}hofParameters=[...elems];elems.length=0;parserState.pos+=2;foundStopChar=true;foundSeparator=false;continue}else if(c===" "){parserState.pos+=1;continue}else if(isSeparatorCharacter(c)){parserState.pos+=1;foundStopChar=true;foundSeparator=true;continue}else if(c===":"&&isPathStart(parserState)){throw["Unexpected ","::",": paths cannot start with ","::"]}else if(isEndCharacter(c)){throw["Unexpected ",c," after ",extra]}if(!foundStopChar){let extra=[];if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",",",", ","=",", or ",endChar,...extra,", found ",c,]}throw["Expected ",","," or ","=",...extra,", found ",c,]}const posBefore=parserState.pos;getFilteredNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;if(hofParameters){foundSeparator=false;if([...elems,...hofParameters].some(x=>x.bindingName)||parserState.isInBinding){throw["Unexpected ","="," within ","->"]}const hofElem=makePrimitiveElement("->",{generics:hofParameters,bindings:new Map([["output",[...elems]]]),typeFilter:null,});elems.length=0;elems[0]=hofElem}parserState.typeFilter=oldTypeFilter;parserState.isInBinding=oldIsInBinding;return{foundSeparator}}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();const match=query.match(REGEX_INVALID_TYPE_FILTER);if(match){throw["Unexpected ",match[0]," in type filter (before ",":",")",]}}function parseInput(query,parserState){let foundStopChar=true;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}else if(parserState.pos>0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}throw["Unexpected ",c]}else if(c===" "){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;getFilteredNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,typeFingerprint:new Uint32Array(4),}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&rawSearchIndex.has(elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}for(const constraints of elem.bindings.values()){for(const constraint of constraints){convertTypeFilterOnElem(constraint)}}}userQuery=userQuery.trim().replace(/\r|\n|\t/g," ");const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,isInBinding:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}async function execQuery(parsedQuery,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=res[2]+"|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}if(obj.ty===TY_IMPORT&&duplicates.has(res[2])){continue}if(duplicates.has(res[2]+"|"+TY_IMPORT)){continue}duplicates.add(obj.fullPath);duplicates.add(res[2]);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}async function sortResults(results,isType,preferredCrate){const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.item=searchIndex[result.id];result.word=searchIndex[result.id].word;result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=searchIndexDeprecated.get(aaa.item.crate).contains(aaa.item.bitIndex);b=searchIndexDeprecated.get(bbb.item.crate).contains(bbb.item.bitIndex);if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=searchIndexEmptyDesc.get(aaa.item.crate).contains(aaa.item.bitIndex);b=searchIndexEmptyDesc.get(bbb.item.crate).contains(bbb.item.bitIndex);if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});return transformResults(result_list)}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb,unboxingDepth,){if(unboxingDepth>=UNBOXING_LIMIT){return false}const mgens=mgensIn===null?null:new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;const fl=fnTypesIn.length;if(ql===1&&queryElems[0].generics.length===0&&queryElems[0].bindings.size===0){const queryElem=queryElems[0];for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,mgens)){continue}if(fnType.id<0&&queryElem.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,queryElem.id);if(!solutionCb||solutionCb(mgensScratch)){return true}}else if(!solutionCb||solutionCb(mgens?new Map(mgens):null)){return true}}for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens,unboxingDepth+1,)){continue}if(fnType.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,0);if(unifyFunctionTypes(whereClause[(-fnType.id)-1],queryElems,whereClause,mgensScratch,solutionCb,unboxingDepth+1,)){return true}}else if(unifyFunctionTypes([...fnType.generics,...Array.from(fnType.bindings.values()).flat()],queryElems,whereClause,mgens?new Map(mgens):null,solutionCb,unboxingDepth+1,)){return true}}return false}const fnTypes=fnTypesIn.slice();const flast=fl-1;const qlast=ql-1;const queryElem=queryElems[qlast];let queryElemsTmp=null;for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,mgens)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==queryElem.id){continue}mgensScratch.set(fnType.id,queryElem.id)}else{mgensScratch=mgens}fnTypes[i]=fnTypes[flast];fnTypes.length=flast;if(!queryElemsTmp){queryElemsTmp=queryElems.slice(0,qlast)}const passesUnification=unifyFunctionTypes(fnTypes,queryElemsTmp,whereClause,mgensScratch,mgensScratch=>{if(fnType.generics.length===0&&queryElem.generics.length===0&&fnType.bindings.size===0&&queryElem.bindings.size===0){return!solutionCb||solutionCb(mgensScratch)}const solution=unifyFunctionTypeCheckBindings(fnType,queryElem,whereClause,mgensScratch,unboxingDepth,);if(!solution){return false}const simplifiedGenerics=solution.simplifiedGenerics;for(const simplifiedMgens of solution.mgens){const passesUnification=unifyFunctionTypes(simplifiedGenerics,queryElem.generics,whereClause,simplifiedMgens,solutionCb,unboxingDepth,);if(passesUnification){return true}}return false},unboxingDepth,);if(passesUnification){return true}fnTypes[flast]=fnTypes[i];fnTypes[i]=fnType;fnTypes.length=fl}for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens,unboxingDepth+1,)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==0){continue}mgensScratch.set(fnType.id,0)}else{mgensScratch=mgens}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;const bindings=fnType.bindings?Array.from(fnType.bindings.values()).flat():[];const passesUnification=unifyFunctionTypes(fnTypes.toSpliced(i,1,...generics,...bindings),queryElems,whereClause,mgensScratch,solutionCb,unboxingDepth+1,);if(passesUnification){return true}}return false}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,mgensIn){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgensIn){if(mgensIn.has(fnType.id)&&mgensIn.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgensIn.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}return true}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(queryElem.id===typeNameIdOfTupleOrUnit&&(fnType.id===typeNameIdOfTuple||fnType.id===typeNameIdOfUnit)){}else if(queryElem.id===typeNameIdOfHof&&(fnType.id===typeNameIdOfFn||fnType.id===typeNameIdOfFnMut||fnType.id===typeNameIdOfFnOnce)){}else if(fnType.id!==queryElem.id||queryElem.id===null){return false}if((fnType.generics.length+fnType.bindings.size)===0&&queryElem.generics.length!==0){return false}if(fnType.bindings.size0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i0){let mgensSolutionSet=[mgensIn];for(const[name,constraints]of queryElem.bindings.entries()){if(mgensSolutionSet.length===0){return false}if(!fnType.bindings.has(name)){return false}const fnTypeBindings=fnType.bindings.get(name);mgensSolutionSet=mgensSolutionSet.flatMap(mgens=>{const newSolutions=[];unifyFunctionTypes(fnTypeBindings,constraints,whereClause,mgens,newMgens=>{newSolutions.push(newMgens);return false},unboxingDepth,);return newSolutions})}if(mgensSolutionSet.length===0){return false}const binds=Array.from(fnType.bindings.entries()).flatMap(entry=>{const[name,constraints]=entry;if(queryElem.bindings.has(name)){return[]}else{return constraints}});if(simplifiedGenerics.length>0){simplifiedGenerics=[...simplifiedGenerics,...binds]}else{simplifiedGenerics=binds}return{simplifiedGenerics,mgens:mgensSolutionSet}}return{simplifiedGenerics,mgens:[mgensIn]}}function unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens,unboxingDepth,){if(unboxingDepth>=UNBOXING_LIMIT){return false}if(fnType.id<0&&queryElem.id>=0){if(!whereClause){return false}if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}const mgensTmp=new Map(mgens);mgensTmp.set(fnType.id,null);return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause,mgensTmp,unboxingDepth,)}else if(fnType.generics.length>0||fnType.bindings.size>0){const simplifiedGenerics=[...fnType.generics,...Array.from(fnType.bindings.values()).flat(),];return checkIfInList(simplifiedGenerics,queryElem,whereClause,mgens,unboxingDepth,)}return false}function checkIfInList(list,elem,whereClause,mgens,unboxingDepth){for(const entry of list){if(checkType(entry,elem,whereClause,mgens,unboxingDepth)){return true}}return false}function checkType(row,elem,whereClause,mgens,unboxingDepth){if(unboxingDepth>=UNBOXING_LIMIT){return false}if(row.bindings.size===0&&elem.bindings.size===0){if(elem.id<0&&mgens===null){return row.id<0||checkIfInList(row.generics,elem,whereClause,mgens,unboxingDepth+1,)}if(row.id>0&&elem.id>0&&elem.pathWithoutLast.length===0&&typePassesFilter(elem.typeFilter,row.ty)&&elem.generics.length===0&&elem.id!==typeNameIdOfArrayOrSlice&&elem.id!==typeNameIdOfTupleOrUnit&&elem.id!==typeNameIdOfHof){return row.id===elem.id||checkIfInList(row.generics,elem,whereClause,mgens,unboxingDepth,)}}return unifyFunctionTypes([row],[elem],whereClause,mgens,null,unboxingDepth)}function checkPath(contains,ty){if(contains.length===0){return 0}const maxPathEditDistance=Math.floor(contains.reduce((acc,next)=>acc+next.length,0)/3,);let ret_dist=maxPathEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;pathiter:for(let i=length-clength;i>=0;i-=1){let dist_total=0;for(let x=0;xmaxPathEditDistance){continue pathiter}dist_total+=dist}}ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}return ret_dist>maxPathEditDistance?null:ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,descShard:item.descShard,descIndex:item.descIndex,exactPath:item.exactPath,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,bitIndex:item.bitIndex,implDisambiguator:item.implDisambiguator,}}async function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{return searchIndexEmptyDesc.get(alias.crate).contains(alias.bitIndex)?"":searchState.loadDesc(alias)};const[crateDescs,descs]=await Promise.all([Promise.all(crateAliases.map(fetchDesc)),Promise.all(aliases.map(fetchDesc)),]);const pushFunc=alias=>{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach((alias,i)=>{alias.desc=descs[i]});aliases.forEach(pushFunc);crateAliases.forEach((alias,i)=>{alias.desc=crateDescs[i]});crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){if(dist<=maxEditDistance||index!==-1){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance,){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let path_dist=0;const fullId=row.id;const tfpDist=compareTypeFingerprints(fullId,parsedQuery.typeFingerprint,);if(tfpDist!==null){const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause,null,0);const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause,null,0);if(in_args){results_in_args.max_dist=Math.max(results_in_args.max_dist||0,tfpDist);const maxDist=results_in_args.sizenormalizedIndex&&normalizedIndex!==-1)){index=normalizedIndex}if(elem.fullPath.length>1){path_dist=checkPath(elem.pathWithoutLast,row);if(path_dist===null){return}}if(parsedQuery.literalSearch){if(row.word===elem.pathLast){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(row.normalizedName,elem.normalizedPathLast,maxEditDistance);if(index===-1&&dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}const tfpDist=compareTypeFingerprints(row.id,parsedQuery.typeFingerprint,);if(tfpDist===null){return}if(results.size>=MAX_RESULTS&&tfpDist>results.max_dist){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens,null,0,)},0,)){return}results.max_dist=Math.max(results.max_dist||0,tfpDist);addIntoResults(results,row.id,pos,0,tfpDist,0,Number.MAX_VALUE)}function innerRunQuery(){const queryLen=parsedQuery.elems.reduce((acc,next)=>acc+next.pathLast.length,0)+parsedQuery.returned.reduce((acc,next)=>acc+next.pathLast.length,0);const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem,isAssocType){const loweredName=elem.pathLast.toLowerCase();if(typeNameIdMap.has(loweredName)&&(isAssocType||!typeNameIdMap.get(loweredName).assocOnly)){elem.id=typeNameIdMap.get(loweredName).id}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,{id,assocOnly}]of typeNameIdMap){const dist=Math.min(editDistance(name,loweredName,maxEditDistance),editDistance(name,elem.normalizedPathLast,maxEditDistance),);if(dist<=matchDist&&dist<=maxEditDistance&&(isAssocType||!assocOnly)){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0&&elem.bindings.size===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}elem.bindings=new Map(Array.from(elem.bindings.entries()).map(entry=>{const[name,constraints]=entry;if(!typeNameIdMap.has(name)){parsedQuery.error=["Type parameter ",name," does not exist",];return[null,[]]}for(const elem2 of constraints){convertNameToId(elem2)}return[typeNameIdMap.get(name).id,constraints]}),)}const fps=new Set();for(const elem of parsedQuery.elems){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}for(const elem of parsedQuery.returned){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}if(parsedQuery.foundElems===1&&parsedQuery.returned.length===0){if(parsedQuery.elems.length===1){const elem=parsedQuery.elems[0];for(let i=0,nSearchIndex=searchIndex.length;i0){const sortQ=(a,b)=>{const ag=a.generics.length===0&&a.bindings.size===0;const bg=b.generics.length===0&&b.bindings.size===0;if(ag!==bg){return ag-bg}const ai=a.id>0;const bi=b.id>0;return ai-bi};parsedQuery.elems.sort(sortQ);parsedQuery.returned.sort(sortQ);for(let i=0,nSearchIndex=searchIndex.length;i{const descs=await Promise.all(list.map(result=>{return searchIndexEmptyDesc.get(result.crate).contains(result.bitIndex)?"":searchState.loadDesc(result)}));for(const[i,result]of list.entries()){result.desc=descs[i]}}));if(parsedQuery.error!==null&&ret.others.length!==0){ret.query.error=null}return ret}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;let exactPath=item.exactPath;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor=type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;exactPath=`${myparent.exactPath}::${myparent.name}`;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}if(item.implDisambiguator!==null){anchor=item.implDisambiguator+"/"+anchor}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html#"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href,`${exactPath}::${name}`]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}async function addTab(array,query,display){const extraClass=display?" active":"";const output=document.createElement("div");if(array.length>0){output.className="search-results "+extraClass;for(const item of array){const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)}}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,array.length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}async function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const[ret_others,ret_in_args,ret_returned]=await Promise.all([addTab(results.others,results.query,true),addTab(results.in_args,results.query,false),addTab(results.returned,results.query,false),]);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";if(rawSearchIndex.size>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

"+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}async function search(forced){const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));await showResults(await execQuery(query,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.length>0?types.map(type=>buildItemSearchType(type,lowercasePaths)):EMPTY_GENERICS_ARRAY}const EMPTY_BINDINGS_MAP=new Map();const EMPTY_GENERICS_ARRAY=[];let TYPES_POOL=new Map();function buildItemSearchType(type,lowercasePaths,isAssocType){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;const BINDINGS_DATA=2;let pathIndex,generics,bindings;if(typeof type==="number"){pathIndex=type;generics=EMPTY_GENERICS_ARRAY;bindings=EMPTY_BINDINGS_MAP}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths,);if(type.length>BINDINGS_DATA&&type[BINDINGS_DATA].length>0){bindings=new Map(type[BINDINGS_DATA].map(binding=>{const[assocType,constraints]=binding;return[buildItemSearchType(assocType,lowercasePaths,true).id,buildItemSearchTypeAll(constraints,lowercasePaths),]}))}else{bindings=EMPTY_BINDINGS_MAP}}let result;if(pathIndex<0){result={id:pathIndex,ty:TY_GENERIC,path:null,exactPath:null,generics,bindings,}}else if(pathIndex===0){result={id:null,ty:null,path:null,exactPath:null,generics,bindings,}}else{const item=lowercasePaths[pathIndex-1];result={id:buildTypeMapIndex(item.name,isAssocType),ty:item.ty,path:item.path,exactPath:item.exactPath,generics,bindings,}}const cr=TYPES_POOL.get(result.id);if(cr){if(cr.generics.length===result.generics.length&&cr.generics!==result.generics&&cr.generics.every((x,i)=>result.generics[i]===x)){result.generics=cr.generics}if(cr.bindings.size===result.bindings.size&&cr.bindings!==result.bindings){let ok=true;for(const[k,v]of cr.bindings.entries()){const v2=result.bindings.get(v);if(!v2){ok=false;break}if(v!==v2&&v.length===v2.length&&v.every((x,i)=>v2[i]===x)){result.bindings.set(k,v)}else if(v!==v2){ok=false;break}}if(ok){result.bindings=cr.bindings}}if(cr.ty===result.ty&&cr.path===result.path&&cr.bindings===result.bindings&&cr.generics===result.generics&&cr.ty===result.ty){return cr}}TYPES_POOL.set(result.id,result);return result}function buildFunctionSearchTypeCallback(lowercasePaths){return functionSearchType=>{if(functionSearchType===0){return null}const INPUTS_DATA=0;const OUTPUT_DATA=1;let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths,)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths,)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i{k=(~~k+0x7ed55d16)+(k<<12);k=(k ^ 0xc761c23c)^(k>>>19);k=(~~k+0x165667b1)+(k<<5);k=(~~k+0xd3a2646c)^(k<<9);k=(~~k+0xfd7046c5)+(k<<3);return(k ^ 0xb55a4f09)^(k>>>16)};const hashint2=k=>{k=~k+(k<<15);k ^=k>>>12;k+=k<<2;k ^=k>>>4;k=Math.imul(k,2057);return k ^(k>>16)};if(input!==null){const h0a=hashint1(input);const h0b=hashint2(input);const h1a=~~(h0a+Math.imul(h0b,2));const h1b=~~(h0a+Math.imul(h0b,3));const h2a=~~(h0a+Math.imul(h0b,4));const h2b=~~(h0a+Math.imul(h0b,5));output[0]|=(1<<(h0a%32))|(1<<(h1b%32));output[1]|=(1<<(h1a%32))|(1<<(h2b%32));output[2]|=(1<<(h2a%32))|(1<<(h0b%32));fps.add(input)}for(const g of type.generics){buildFunctionTypeFingerprint(g,output,fps)}const fb={id:null,ty:0,generics:EMPTY_GENERICS_ARRAY,bindings:EMPTY_BINDINGS_MAP,};for(const[k,v]of type.bindings.entries()){fb.id=k;fb.generics=v;buildFunctionTypeFingerprint(fb,output,fps)}output[3]=fps.size}function compareTypeFingerprints(fullId,queryFingerprint){const fh0=functionTypeFingerprint[fullId*4];const fh1=functionTypeFingerprint[(fullId*4)+1];const fh2=functionTypeFingerprint[(fullId*4)+2];const[qh0,qh1,qh2]=queryFingerprint;const[in0,in1,in2]=[fh0&qh0,fh1&qh1,fh2&qh2];if((in0 ^ qh0)||(in1 ^ qh1)||(in2 ^ qh2)){return null}return functionTypeFingerprint[(fullId*4)+3]}class VlqHexDecoder{constructor(string,cons){this.string=string;this.cons=cons;this.offset=0;this.backrefQueue=[]}decodeList(){const cb="}".charCodeAt(0);let c=this.string.charCodeAt(this.offset);const ret=[];while(c!==cb){ret.push(this.decode());c=this.string.charCodeAt(this.offset)}this.offset+=1;return ret}decode(){const[ob,la]=["{","`"].map(c=>c.charCodeAt(0));let n=0;let c=this.string.charCodeAt(this.offset);if(c===ob){this.offset+=1;return this.decodeList()}while(c>1];this.offset+=1;return sign?-value:value}next(){const c=this.string.charCodeAt(this.offset);const[zero,ua,la]=["0","@","`"].map(c=>c.charCodeAt(0));if(c>=zero&&c16){this.backrefQueue.pop()}return result}}class RoaringBitmap{constructor(str){const strdecoded=atob(str);const u8array=new Uint8Array(strdecoded.length);for(let j=0;j=4){offsets=[];for(let j=0;j>3]&(1<<(j&0x7))){const runcount=(u8array[i]|(u8array[i+1]<<8));i+=2;this.containers.push(new RoaringBitmapRun(runcount,u8array.slice(i,i+(runcount*4)),));i+=runcount*4}else if(this.cardinalities[j]>=4096){this.containers.push(new RoaringBitmapBits(u8array.slice(i,i+8192)));i+=8192}else{const end=this.cardinalities[j]*2;this.containers.push(new RoaringBitmapArray(this.cardinalities[j],u8array.slice(i,i+end),));i+=end}}}contains(keyvalue){const key=keyvalue>>16;const value=keyvalue&0xFFFF;for(let i=0;i=start&&value<=(start+lenm1)){return true}}return false}}class RoaringBitmapArray{constructor(cardinality,array){this.cardinality=cardinality;this.array=array}contains(value){const l=this.cardinality*2;for(let i=0;i>3]&(1<<(value&7)))}}function buildIndex(rawSearchIndex){searchIndex=[];searchIndexDeprecated=new Map();searchIndexEmptyDesc=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;for(const crate of rawSearchIndex.values()){id+=crate.t.length+1}functionTypeFingerprint=new Uint32Array((id+1)*4);id=0;for(const[crate,crateCorpus]of rawSearchIndex){const itemDescShardDecoder=new VlqHexDecoder(crateCorpus.D,noop=>noop);let descShard={crate,shard:0,start:0,len:itemDescShardDecoder.next(),promise:null,resolve:null,};const descShardList=[descShard];searchIndexDeprecated.set(crate,new RoaringBitmap(crateCorpus.c));searchIndexEmptyDesc.set(crate,new RoaringBitmap(crateCorpus.e));let descIndex=0;const crateRow={crate,ty:3,name:crate,path:"",descShard,descIndex,exactPath:"",desc:crateCorpus.doc,parent:undefined,type:null,id,word:crate,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),bitIndex:0,implDisambiguator:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;if(!searchIndexEmptyDesc.get(crate).contains(0)){descIndex+=1}const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemReexports=new Map(crateCorpus.r);const itemParentIdxs=crateCorpus.i;const implDisambiguator=new Map(crateCorpus.b);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];const itemFunctionDecoder=new VlqHexDecoder(crateCorpus.f,buildFunctionSearchTypeCallback(lowercasePaths),);let len=paths.length;let lastPath=itemPaths.get(0);for(let i=0;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}const exactPath=elem.length>3?itemPaths.get(elem[3]):path;lowercasePaths.push({ty,name:name.toLowerCase(),path,exactPath});paths[i]={ty,name,path,exactPath}}lastPath="";len=itemTypes.length;for(let i=0;i=descShard.len&&!searchIndexEmptyDesc.get(crate).contains(bitIndex)){descShard={crate,shard:descShard.shard+1,start:descShard.start+descShard.len,len:itemDescShardDecoder.next(),promise:null,resolve:null,};descIndex=0;descShardList.push(descShard)}let word="";if(typeof itemNames[i]==="string"){word=itemNames[i].toLowerCase()}const path=itemPaths.has(i)?itemPaths.get(i):lastPath;const type=itemFunctionDecoder.next();if(type!==null){if(type){const fp=functionTypeFingerprint.subarray(id*4,(id+1)*4);const fps=new Set();for(const t of type.inputs){buildFunctionTypeFingerprint(t,fp,fps)}for(const t of type.output){buildFunctionTypeFingerprint(t,fp,fps)}for(const w of type.where_clause){for(const t of w){buildFunctionTypeFingerprint(t,fp,fps)}}}}const row={crate,ty:itemTypes.charCodeAt(i)-charA,name:itemNames[i],path,descShard,descIndex,exactPath:itemReexports.has(i)?itemPaths.get(itemReexports.get(i)):path,parent:itemParentIdxs[i]>0?paths[itemParentIdxs[i]-1]:undefined,type,id,word,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),bitIndex,implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path;if(!searchIndexEmptyDesc.get(crate).contains(bitIndex)){descIndex+=1}}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!Object.prototype.hasOwnProperty.call(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=itemTypes.length;searchState.descShards.set(crate,descShardList)}TYPES_POOL=new Map()}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;e.preventDefault();search()}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(true)}buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch(new Map())}})() \ No newline at end of file diff --git a/static.files/settings-4313503d2e1961c2.js b/static.files/settings-4313503d2e1961c2.js new file mode 100644 index 00000000..ab425fe4 --- /dev/null +++ b/static.files/settings-4313503d2e1961c2.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break;case"hide-sidebar":if(value===true){addClass(document.documentElement,"hide-sidebar")}else{removeClass(document.documentElement,"hide-sidebar")}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Hide persistent navigation bar","js_name":"hide-sidebar","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display="";onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"),el=>{const val=getSettingValue(el.id);const checked=val==="true";if(checked!==el.checked&&val!==null){el.checked=checked}})}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(settingsMenu.contains(event.target)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-e66d777a5a92e9b2.js b/static.files/src-script-e66d777a5a92e9b2.js new file mode 100644 index 00000000..d0aebb85 --- /dev/null +++ b/static.files/src-script-e66d777a5a92e9b2.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth{removeClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","false")};window.rustdocShowSourceSidebar=()=>{addClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","true")};window.rustdocToggleSrcSidebar=()=>{if(document.documentElement.classList.contains("src-sidebar-expanded")){window.rustdocCloseSourceSidebar()}else{window.rustdocShowSourceSidebar()}};function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;for(const[key,source]of srcIndex){source[NAME_OFFSET]=key;hasFoundFile=createDirEntry(source,sidebar,"",hasFoundFile)}container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}function highlightSrcLines(){const match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",highlightSrcLines);onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-118b08c4c78b968e.js b/static.files/storage-118b08c4c78b968e.js new file mode 100644 index 00000000..98189467 --- /dev/null +++ b/static.files/storage-118b08c4c78b968e.js @@ -0,0 +1,24 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func){for(const elem of arr){if(func(elem)){return true}}return false}function onEachLazy(lazyArray,func){return onEach(Array.prototype.slice.call(lazyArray),func)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){const themeNames=getVar("themes").split(",").filter(t=>t);themeNames.push(...builtinThemes);if(themeNames.indexOf(newThemeName)===-1){return}if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+encodeURIComponent(newThemeName)+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}if(getSettingValue("hide-sidebar")==="true"){addClass(document.documentElement,"hide-sidebar")}function updateSidebarWidth(){const desktopSidebarWidth=getSettingValue("desktop-sidebar-width");if(desktopSidebarWidth&&desktopSidebarWidth!=="null"){document.documentElement.style.setProperty("--desktop-sidebar-width",desktopSidebarWidth+"px",)}const srcSidebarWidth=getSettingValue("src-sidebar-width");if(srcSidebarWidth&&srcSidebarWidth!=="null"){document.documentElement.style.setProperty("--src-sidebar-width",srcSidebarWidth+"px",)}}updateSidebarWidth();window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0);setTimeout(updateSidebarWidth,0)}});class RustdocSearchElement extends HTMLElement{constructor(){super()}connectedCallback(){const rootPath=getVar("root-path");const currentCrate=getVar("current-crate");this.innerHTML=``}}window.customElements.define("rustdoc-search",RustdocSearchElement) \ No newline at end of file diff --git a/trait.impl/composable/dependencies/values/trait.DependencyDefault.js b/trait.impl/composable/dependencies/values/trait.DependencyDefault.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/dependencies/values/trait.DependencyDefault.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/effects/trait.Effects.js b/trait.impl/composable/effects/trait.Effects.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/effects/trait.Effects.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/effects/trait.Scheduler.js b/trait.impl/composable/effects/trait.Scheduler.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/effects/trait.Scheduler.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/reducer/trait.Reducer.js b/trait.impl/composable/reducer/trait.Reducer.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/reducer/trait.Reducer.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/store/testing/clock/trait.TestClock.js b/trait.impl/composable/store/testing/clock/trait.TestClock.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/store/testing/clock/trait.TestClock.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/trait.Effects.js b/trait.impl/composable/trait.Effects.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/trait.Effects.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/views/output/trait.Output.js b/trait.impl/composable/views/output/trait.Output.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/views/output/trait.Output.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/views/shapes/trait.Path.js b/trait.impl/composable/views/shapes/trait.Path.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/views/shapes/trait.Path.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/composable/views/trait.View.js b/trait.impl/composable/views/trait.View.js new file mode 100644 index 00000000..0a1326b8 --- /dev/null +++ b/trait.impl/composable/views/trait.View.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/borrow/trait.Borrow.js b/trait.impl/core/borrow/trait.Borrow.js new file mode 100644 index 00000000..0aa40b9d --- /dev/null +++ b/trait.impl/core/borrow/trait.Borrow.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl<T: DependencyDefault> Borrow<T> for Dependency<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/clone/trait.Clone.js b/trait.impl/core/clone/trait.Clone.js new file mode 100644 index 00000000..18d29a8d --- /dev/null +++ b/trait.impl/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Clone for Event"],["impl Clone for Gesture"],["impl Clone for Response"],["impl Clone for Scale"],["impl Clone for Id"],["impl Clone for Values"],["impl<'a> Clone for FontConfig<'a>"],["impl<Parent: Clone, Child> Clone for Scoped<Parent, Child>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Eq.js b/trait.impl/core/cmp/trait.Eq.js new file mode 100644 index 00000000..a495ba6a --- /dev/null +++ b/trait.impl/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Eq for Response"],["impl Eq for Id"],["impl Eq for Values"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialEq.js b/trait.impl/core/cmp/trait.PartialEq.js new file mode 100644 index 00000000..9e095c52 --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl PartialEq for Response"],["impl PartialEq for Id"],["impl PartialEq for Values"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.AsRef.js b/trait.impl/core/convert/trait.AsRef.js new file mode 100644 index 00000000..e737c323 --- /dev/null +++ b/trait.impl/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl<T: DependencyDefault> AsRef<T> for Dependency<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.From.js b/trait.impl/core/convert/trait.From.js new file mode 100644 index 00000000..997d01c4 --- /dev/null +++ b/trait.impl/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl From<(u32, u32)> for Event"],["impl From<Gesture> for Event"],["impl From<()> for Event"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.TryFrom.js b/trait.impl/core/convert/trait.TryFrom.js new file mode 100644 index 00000000..21fba4c0 --- /dev/null +++ b/trait.impl/core/convert/trait.TryFrom.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl TryFrom<Event> for (u32, u32)"],["impl TryFrom<Event> for Gesture"],["impl TryFrom<Event> for ()"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/default/trait.Default.js b/trait.impl/core/default/trait.Default.js new file mode 100644 index 00000000..b94e45e5 --- /dev/null +++ b/trait.impl/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Default for Scale"],["impl Default for Values"],["impl Default for Inter<'static, L>"],["impl Default for Inter<'static, M>"],["impl Default for Inter<'static, S>"],["impl Default for Inter<'static, L>"],["impl Default for Inter<'static, M>"],["impl Default for Inter<'static, S>"],["impl Default for Inter<'static, L>"],["impl Default for Inter<'static, M>"],["impl Default for Inter<'static, S>"],["impl<State> Default for Store<State>
where\n State: Default + Reducer,\n <State as Reducer>::Action: Send + 'static,\n <State as Reducer>::Output: Send + From<State> + 'static,
"],["impl<State> Default for TestStore<State>
where\n State: Default + Reducer,\n <State as Reducer>::Action: Debug,
"],["impl<T> Default for Dependency<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Debug.js b/trait.impl/core/fmt/trait.Debug.js new file mode 100644 index 00000000..ac0de403 --- /dev/null +++ b/trait.impl/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Debug for Response"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Copy.js b/trait.impl/core/marker/trait.Copy.js new file mode 100644 index 00000000..86078dbc --- /dev/null +++ b/trait.impl/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Copy for Event"],["impl Copy for Gesture"],["impl Copy for Response"],["impl Copy for Scale"],["impl Copy for Id"],["impl Copy for Values"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Freeze.js b/trait.impl/core/marker/trait.Freeze.js new file mode 100644 index 00000000..bdb9a555 --- /dev/null +++ b/trait.impl/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl !Freeze for Spacer",1,["composable::views::layout::spacing::Spacer"]],["impl Freeze for Interval",1,["composable::effects::Interval"]],["impl Freeze for Event",1,["composable::views::Event"]],["impl Freeze for Gesture",1,["composable::views::Gesture"]],["impl Freeze for Response",1,["composable::views::gesture::recognizer::Response"]],["impl Freeze for Scale",1,["composable::views::ui::accessibility::Scale"]],["impl Freeze for Id",1,["composable::views::gesture::Id"]],["impl Freeze for Values",1,["composable::views::gesture::Values"]],["impl Freeze for Output",1,["composable::views::output::gpu::Output"]],["impl Freeze for Circle",1,["composable::views::shapes::Circle"]],["impl Freeze for ContinuousRoundedRectangle",1,["composable::views::shapes::ContinuousRoundedRectangle"]],["impl Freeze for Ellipse",1,["composable::views::shapes::Ellipse"]],["impl Freeze for Rectangle",1,["composable::views::shapes::Rectangle"]],["impl Freeze for RoundedRectangle",1,["composable::views::shapes::RoundedRectangle"]],["impl Freeze for Output",1,["composable::views::output::svg::Output"]],["impl Freeze for L",1,["composable::views::ui::font::typography::body::L"]],["impl Freeze for M",1,["composable::views::ui::font::typography::body::M"]],["impl Freeze for S",1,["composable::views::ui::font::typography::body::S"]],["impl Freeze for L",1,["composable::views::ui::font::typography::label::L"]],["impl Freeze for M",1,["composable::views::ui::font::typography::label::M"]],["impl Freeze for S",1,["composable::views::ui::font::typography::label::S"]],["impl Freeze for L",1,["composable::views::ui::font::typography::title::L"]],["impl Freeze for M",1,["composable::views::ui::font::typography::title::M"]],["impl Freeze for S",1,["composable::views::ui::font::typography::title::S"]],["impl<'a> Freeze for Font<'a>",1,["composable::views::text::font::Font"]],["impl<'a> Freeze for FontConfig<'a>",1,["composable::views::text::font::FontConfig"]],["impl<'a, Style> Freeze for Inter<'a, Style>",1,["composable::views::ui::font::Inter"]],["impl<Parent, Child> Freeze for Scoped<Parent, Child>
where\n Parent: Freeze,
",1,["composable::effects::Scoped"]],["impl<State> !Freeze for TestStore<State>",1,["composable::store::testing::TestStore"]],["impl<State> Freeze for Store<State>",1,["composable::store::Store"]],["impl<T> !Freeze for Dependency<T>",1,["composable::dependencies::values::Dependency"]],["impl<V> Freeze for Fixed<V>
where\n V: Freeze,
",1,["composable::views::modifiers::fixed::Fixed"]],["impl<V> Freeze for FixedHeight<V>
where\n V: Freeze,
",1,["composable::views::modifiers::fixed::FixedHeight"]],["impl<V> Freeze for FixedWidth<V>
where\n V: Freeze,
",1,["composable::views::modifiers::fixed::FixedWidth"]],["impl<V> Freeze for Padding<V>
where\n V: Freeze,
",1,["composable::views::modifiers::padding::Padding"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Send.js b/trait.impl/core/marker/trait.Send.js new file mode 100644 index 00000000..f57ad5c4 --- /dev/null +++ b/trait.impl/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Send for Interval",1,["composable::effects::Interval"]],["impl Send for Event",1,["composable::views::Event"]],["impl Send for Gesture",1,["composable::views::Gesture"]],["impl Send for Response",1,["composable::views::gesture::recognizer::Response"]],["impl Send for Scale",1,["composable::views::ui::accessibility::Scale"]],["impl Send for Id",1,["composable::views::gesture::Id"]],["impl Send for Values",1,["composable::views::gesture::Values"]],["impl Send for Output",1,["composable::views::output::gpu::Output"]],["impl Send for Circle",1,["composable::views::shapes::Circle"]],["impl Send for ContinuousRoundedRectangle",1,["composable::views::shapes::ContinuousRoundedRectangle"]],["impl Send for Ellipse",1,["composable::views::shapes::Ellipse"]],["impl Send for Rectangle",1,["composable::views::shapes::Rectangle"]],["impl Send for RoundedRectangle",1,["composable::views::shapes::RoundedRectangle"]],["impl Send for Spacer",1,["composable::views::layout::spacing::Spacer"]],["impl Send for Output",1,["composable::views::output::svg::Output"]],["impl Send for L",1,["composable::views::ui::font::typography::body::L"]],["impl Send for M",1,["composable::views::ui::font::typography::body::M"]],["impl Send for S",1,["composable::views::ui::font::typography::body::S"]],["impl Send for L",1,["composable::views::ui::font::typography::label::L"]],["impl Send for M",1,["composable::views::ui::font::typography::label::M"]],["impl Send for S",1,["composable::views::ui::font::typography::label::S"]],["impl Send for L",1,["composable::views::ui::font::typography::title::L"]],["impl Send for M",1,["composable::views::ui::font::typography::title::M"]],["impl Send for S",1,["composable::views::ui::font::typography::title::S"]],["impl<'a> Send for Font<'a>",1,["composable::views::text::font::Font"]],["impl<'a> Send for FontConfig<'a>",1,["composable::views::text::font::FontConfig"]],["impl<'a, Style> Send for Inter<'a, Style>
where\n Style: Send,
",1,["composable::views::ui::font::Inter"]],["impl<Parent, Child> Send for Scoped<Parent, Child>
where\n Parent: Send,\n Child: Send,
",1,["composable::effects::Scoped"]],["impl<State> !Send for TestStore<State>",1,["composable::store::testing::TestStore"]],["impl<State> Send for Store<State>
where\n <State as Reducer>::Action: Send,
",1,["composable::store::Store"]],["impl<T> !Send for Dependency<T>",1,["composable::dependencies::values::Dependency"]],["impl<V> Send for Fixed<V>
where\n V: Send,
",1,["composable::views::modifiers::fixed::Fixed"]],["impl<V> Send for FixedHeight<V>
where\n V: Send,
",1,["composable::views::modifiers::fixed::FixedHeight"]],["impl<V> Send for FixedWidth<V>
where\n V: Send,
",1,["composable::views::modifiers::fixed::FixedWidth"]],["impl<V> Send for Padding<V>
where\n V: Send,
",1,["composable::views::modifiers::padding::Padding"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.StructuralPartialEq.js b/trait.impl/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 00000000..6afd2456 --- /dev/null +++ b/trait.impl/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl StructuralPartialEq for Response"],["impl StructuralPartialEq for Id"],["impl StructuralPartialEq for Values"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Sync.js b/trait.impl/core/marker/trait.Sync.js new file mode 100644 index 00000000..8966d8ad --- /dev/null +++ b/trait.impl/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl !Sync for Spacer",1,["composable::views::layout::spacing::Spacer"]],["impl Sync for Interval",1,["composable::effects::Interval"]],["impl Sync for Event",1,["composable::views::Event"]],["impl Sync for Gesture",1,["composable::views::Gesture"]],["impl Sync for Response",1,["composable::views::gesture::recognizer::Response"]],["impl Sync for Scale",1,["composable::views::ui::accessibility::Scale"]],["impl Sync for Id",1,["composable::views::gesture::Id"]],["impl Sync for Values",1,["composable::views::gesture::Values"]],["impl Sync for Output",1,["composable::views::output::gpu::Output"]],["impl Sync for Circle",1,["composable::views::shapes::Circle"]],["impl Sync for ContinuousRoundedRectangle",1,["composable::views::shapes::ContinuousRoundedRectangle"]],["impl Sync for Ellipse",1,["composable::views::shapes::Ellipse"]],["impl Sync for Rectangle",1,["composable::views::shapes::Rectangle"]],["impl Sync for RoundedRectangle",1,["composable::views::shapes::RoundedRectangle"]],["impl Sync for Output",1,["composable::views::output::svg::Output"]],["impl Sync for L",1,["composable::views::ui::font::typography::body::L"]],["impl Sync for M",1,["composable::views::ui::font::typography::body::M"]],["impl Sync for S",1,["composable::views::ui::font::typography::body::S"]],["impl Sync for L",1,["composable::views::ui::font::typography::label::L"]],["impl Sync for M",1,["composable::views::ui::font::typography::label::M"]],["impl Sync for S",1,["composable::views::ui::font::typography::label::S"]],["impl Sync for L",1,["composable::views::ui::font::typography::title::L"]],["impl Sync for M",1,["composable::views::ui::font::typography::title::M"]],["impl Sync for S",1,["composable::views::ui::font::typography::title::S"]],["impl<'a> Sync for Font<'a>",1,["composable::views::text::font::Font"]],["impl<'a> Sync for FontConfig<'a>",1,["composable::views::text::font::FontConfig"]],["impl<'a, Style> Sync for Inter<'a, Style>
where\n Style: Sync,
",1,["composable::views::ui::font::Inter"]],["impl<Parent, Child> Sync for Scoped<Parent, Child>
where\n Parent: Sync,\n Child: Sync,
",1,["composable::effects::Scoped"]],["impl<State> !Sync for TestStore<State>",1,["composable::store::testing::TestStore"]],["impl<State> Sync for Store<State>
where\n <State as Reducer>::Action: Send,
",1,["composable::store::Store"]],["impl<T> !Sync for Dependency<T>",1,["composable::dependencies::values::Dependency"]],["impl<V> Sync for Fixed<V>
where\n V: Sync,
",1,["composable::views::modifiers::fixed::Fixed"]],["impl<V> Sync for FixedHeight<V>
where\n V: Sync,
",1,["composable::views::modifiers::fixed::FixedHeight"]],["impl<V> Sync for FixedWidth<V>
where\n V: Sync,
",1,["composable::views::modifiers::fixed::FixedWidth"]],["impl<V> Sync for Padding<V>
where\n V: Sync,
",1,["composable::views::modifiers::padding::Padding"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Unpin.js b/trait.impl/core/marker/trait.Unpin.js new file mode 100644 index 00000000..a53c6a96 --- /dev/null +++ b/trait.impl/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl Unpin for Interval",1,["composable::effects::Interval"]],["impl Unpin for Event",1,["composable::views::Event"]],["impl Unpin for Gesture",1,["composable::views::Gesture"]],["impl Unpin for Response",1,["composable::views::gesture::recognizer::Response"]],["impl Unpin for Scale",1,["composable::views::ui::accessibility::Scale"]],["impl Unpin for Id",1,["composable::views::gesture::Id"]],["impl Unpin for Values",1,["composable::views::gesture::Values"]],["impl Unpin for Output",1,["composable::views::output::gpu::Output"]],["impl Unpin for Circle",1,["composable::views::shapes::Circle"]],["impl Unpin for ContinuousRoundedRectangle",1,["composable::views::shapes::ContinuousRoundedRectangle"]],["impl Unpin for Ellipse",1,["composable::views::shapes::Ellipse"]],["impl Unpin for Rectangle",1,["composable::views::shapes::Rectangle"]],["impl Unpin for RoundedRectangle",1,["composable::views::shapes::RoundedRectangle"]],["impl Unpin for Spacer",1,["composable::views::layout::spacing::Spacer"]],["impl Unpin for Output",1,["composable::views::output::svg::Output"]],["impl Unpin for L",1,["composable::views::ui::font::typography::body::L"]],["impl Unpin for M",1,["composable::views::ui::font::typography::body::M"]],["impl Unpin for S",1,["composable::views::ui::font::typography::body::S"]],["impl Unpin for L",1,["composable::views::ui::font::typography::label::L"]],["impl Unpin for M",1,["composable::views::ui::font::typography::label::M"]],["impl Unpin for S",1,["composable::views::ui::font::typography::label::S"]],["impl Unpin for L",1,["composable::views::ui::font::typography::title::L"]],["impl Unpin for M",1,["composable::views::ui::font::typography::title::M"]],["impl Unpin for S",1,["composable::views::ui::font::typography::title::S"]],["impl<'a> Unpin for Font<'a>",1,["composable::views::text::font::Font"]],["impl<'a> Unpin for FontConfig<'a>",1,["composable::views::text::font::FontConfig"]],["impl<'a, Style> Unpin for Inter<'a, Style>
where\n Style: Unpin,
",1,["composable::views::ui::font::Inter"]],["impl<Parent, Child> Unpin for Scoped<Parent, Child>
where\n Parent: Unpin,\n Child: Unpin,
",1,["composable::effects::Scoped"]],["impl<State> Unpin for Store<State>",1,["composable::store::Store"]],["impl<State> Unpin for TestStore<State>
where\n State: Unpin,
",1,["composable::store::testing::TestStore"]],["impl<T> Unpin for Dependency<T>",1,["composable::dependencies::values::Dependency"]],["impl<V> Unpin for Fixed<V>
where\n V: Unpin,
",1,["composable::views::modifiers::fixed::Fixed"]],["impl<V> Unpin for FixedHeight<V>
where\n V: Unpin,
",1,["composable::views::modifiers::fixed::FixedHeight"]],["impl<V> Unpin for FixedWidth<V>
where\n V: Unpin,
",1,["composable::views::modifiers::fixed::FixedWidth"]],["impl<V> Unpin for Padding<V>
where\n V: Unpin,
",1,["composable::views::modifiers::padding::Padding"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/deref/trait.Deref.js b/trait.impl/core/ops/deref/trait.Deref.js new file mode 100644 index 00000000..e7685633 --- /dev/null +++ b/trait.impl/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl<'a, Style> Deref for Inter<'a, Style>"],["impl<T: DependencyDefault> Deref for Dependency<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/drop/trait.Drop.js b/trait.impl/core/ops/drop/trait.Drop.js new file mode 100644 index 00000000..b539d2ed --- /dev/null +++ b/trait.impl/core/ops/drop/trait.Drop.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl<State: Reducer> Drop for TestStore<State>
where\n <State as Reducer>::Action: Debug,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 00000000..87314220 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl !RefUnwindSafe for Spacer",1,["composable::views::layout::spacing::Spacer"]],["impl !RefUnwindSafe for Output",1,["composable::views::output::svg::Output"]],["impl RefUnwindSafe for Interval",1,["composable::effects::Interval"]],["impl RefUnwindSafe for Event",1,["composable::views::Event"]],["impl RefUnwindSafe for Gesture",1,["composable::views::Gesture"]],["impl RefUnwindSafe for Response",1,["composable::views::gesture::recognizer::Response"]],["impl RefUnwindSafe for Scale",1,["composable::views::ui::accessibility::Scale"]],["impl RefUnwindSafe for Id",1,["composable::views::gesture::Id"]],["impl RefUnwindSafe for Values",1,["composable::views::gesture::Values"]],["impl RefUnwindSafe for Output",1,["composable::views::output::gpu::Output"]],["impl RefUnwindSafe for Circle",1,["composable::views::shapes::Circle"]],["impl RefUnwindSafe for ContinuousRoundedRectangle",1,["composable::views::shapes::ContinuousRoundedRectangle"]],["impl RefUnwindSafe for Ellipse",1,["composable::views::shapes::Ellipse"]],["impl RefUnwindSafe for Rectangle",1,["composable::views::shapes::Rectangle"]],["impl RefUnwindSafe for RoundedRectangle",1,["composable::views::shapes::RoundedRectangle"]],["impl RefUnwindSafe for L",1,["composable::views::ui::font::typography::body::L"]],["impl RefUnwindSafe for M",1,["composable::views::ui::font::typography::body::M"]],["impl RefUnwindSafe for S",1,["composable::views::ui::font::typography::body::S"]],["impl RefUnwindSafe for L",1,["composable::views::ui::font::typography::label::L"]],["impl RefUnwindSafe for M",1,["composable::views::ui::font::typography::label::M"]],["impl RefUnwindSafe for S",1,["composable::views::ui::font::typography::label::S"]],["impl RefUnwindSafe for L",1,["composable::views::ui::font::typography::title::L"]],["impl RefUnwindSafe for M",1,["composable::views::ui::font::typography::title::M"]],["impl RefUnwindSafe for S",1,["composable::views::ui::font::typography::title::S"]],["impl<'a> !RefUnwindSafe for Font<'a>",1,["composable::views::text::font::Font"]],["impl<'a> RefUnwindSafe for FontConfig<'a>",1,["composable::views::text::font::FontConfig"]],["impl<'a, Style> !RefUnwindSafe for Inter<'a, Style>",1,["composable::views::ui::font::Inter"]],["impl<Parent, Child> RefUnwindSafe for Scoped<Parent, Child>
where\n Parent: RefUnwindSafe,\n Child: RefUnwindSafe,
",1,["composable::effects::Scoped"]],["impl<State> !RefUnwindSafe for Store<State>",1,["composable::store::Store"]],["impl<State> !RefUnwindSafe for TestStore<State>",1,["composable::store::testing::TestStore"]],["impl<T> !RefUnwindSafe for Dependency<T>",1,["composable::dependencies::values::Dependency"]],["impl<V> RefUnwindSafe for Fixed<V>
where\n V: RefUnwindSafe,
",1,["composable::views::modifiers::fixed::Fixed"]],["impl<V> RefUnwindSafe for FixedHeight<V>
where\n V: RefUnwindSafe,
",1,["composable::views::modifiers::fixed::FixedHeight"]],["impl<V> RefUnwindSafe for FixedWidth<V>
where\n V: RefUnwindSafe,
",1,["composable::views::modifiers::fixed::FixedWidth"]],["impl<V> RefUnwindSafe for Padding<V>
where\n V: RefUnwindSafe,
",1,["composable::views::modifiers::padding::Padding"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 00000000..528664a0 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"composable":[["impl !UnwindSafe for Output",1,["composable::views::output::svg::Output"]],["impl UnwindSafe for Interval",1,["composable::effects::Interval"]],["impl UnwindSafe for Event",1,["composable::views::Event"]],["impl UnwindSafe for Gesture",1,["composable::views::Gesture"]],["impl UnwindSafe for Response",1,["composable::views::gesture::recognizer::Response"]],["impl UnwindSafe for Scale",1,["composable::views::ui::accessibility::Scale"]],["impl UnwindSafe for Id",1,["composable::views::gesture::Id"]],["impl UnwindSafe for Values",1,["composable::views::gesture::Values"]],["impl UnwindSafe for Output",1,["composable::views::output::gpu::Output"]],["impl UnwindSafe for Circle",1,["composable::views::shapes::Circle"]],["impl UnwindSafe for ContinuousRoundedRectangle",1,["composable::views::shapes::ContinuousRoundedRectangle"]],["impl UnwindSafe for Ellipse",1,["composable::views::shapes::Ellipse"]],["impl UnwindSafe for Rectangle",1,["composable::views::shapes::Rectangle"]],["impl UnwindSafe for RoundedRectangle",1,["composable::views::shapes::RoundedRectangle"]],["impl UnwindSafe for Spacer",1,["composable::views::layout::spacing::Spacer"]],["impl UnwindSafe for L",1,["composable::views::ui::font::typography::body::L"]],["impl UnwindSafe for M",1,["composable::views::ui::font::typography::body::M"]],["impl UnwindSafe for S",1,["composable::views::ui::font::typography::body::S"]],["impl UnwindSafe for L",1,["composable::views::ui::font::typography::label::L"]],["impl UnwindSafe for M",1,["composable::views::ui::font::typography::label::M"]],["impl UnwindSafe for S",1,["composable::views::ui::font::typography::label::S"]],["impl UnwindSafe for L",1,["composable::views::ui::font::typography::title::L"]],["impl UnwindSafe for M",1,["composable::views::ui::font::typography::title::M"]],["impl UnwindSafe for S",1,["composable::views::ui::font::typography::title::S"]],["impl<'a> !UnwindSafe for Font<'a>",1,["composable::views::text::font::Font"]],["impl<'a> UnwindSafe for FontConfig<'a>",1,["composable::views::text::font::FontConfig"]],["impl<'a, Style> !UnwindSafe for Inter<'a, Style>",1,["composable::views::ui::font::Inter"]],["impl<Parent, Child> UnwindSafe for Scoped<Parent, Child>
where\n Parent: UnwindSafe,\n Child: UnwindSafe,
",1,["composable::effects::Scoped"]],["impl<State> !UnwindSafe for Store<State>",1,["composable::store::Store"]],["impl<State> !UnwindSafe for TestStore<State>",1,["composable::store::testing::TestStore"]],["impl<T> UnwindSafe for Dependency<T>
where\n T: RefUnwindSafe,
",1,["composable::dependencies::values::Dependency"]],["impl<V> UnwindSafe for Fixed<V>
where\n V: UnwindSafe,
",1,["composable::views::modifiers::fixed::Fixed"]],["impl<V> UnwindSafe for FixedHeight<V>
where\n V: UnwindSafe,
",1,["composable::views::modifiers::fixed::FixedHeight"]],["impl<V> UnwindSafe for FixedWidth<V>
where\n V: UnwindSafe,
",1,["composable::views::modifiers::fixed::FixedWidth"]],["impl<V> UnwindSafe for Padding<V>
where\n V: UnwindSafe,
",1,["composable::views::modifiers::padding::Padding"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/type.impl/core/cell/struct.Cell.js b/type.impl/core/cell/struct.Cell.js new file mode 100644 index 00000000..8d7e06aa --- /dev/null +++ b/type.impl/core/cell/struct.Cell.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"composable":[["
source§

impl<T> Cell<T>

1.0.0 (const: 1.24.0) · source

pub const fn new(value: T) -> Cell<T>

Creates a new Cell containing the given value.

\n
§Examples
\n
use std::cell::Cell;\n\nlet c = Cell::new(5);
\n
1.0.0 · source

pub fn set(&self, val: T)

Sets the contained value.

\n
§Examples
\n
use std::cell::Cell;\n\nlet c = Cell::new(5);\n\nc.set(10);
\n
1.17.0 · source

pub fn swap(&self, other: &Cell<T>)

Swaps the values of two Cells.\nDifference with std::mem::swap is that this function doesn’t require &mut reference.

\n
§Panics
\n

This function will panic if self and other are different Cells that partially overlap.\n(Using just standard library methods, it is impossible to create such partially overlapping Cells.\nHowever, unsafe code is allowed to e.g. create two &Cell<[i32; 2]> that partially overlap.)

\n
§Examples
\n
use std::cell::Cell;\n\nlet c1 = Cell::new(5i32);\nlet c2 = Cell::new(10i32);\nc1.swap(&c2);\nassert_eq!(10, c1.get());\nassert_eq!(5, c2.get());
\n
1.17.0 · source

pub fn replace(&self, val: T) -> T

Replaces the contained value with val, and returns the old contained value.

\n
§Examples
\n
use std::cell::Cell;\n\nlet cell = Cell::new(5);\nassert_eq!(cell.get(), 5);\nassert_eq!(cell.replace(10), 5);\nassert_eq!(cell.get(), 10);
\n
1.17.0 (const: unstable) · source

pub fn into_inner(self) -> T

Unwraps the value, consuming the cell.

\n
§Examples
\n
use std::cell::Cell;\n\nlet c = Cell::new(5);\nlet five = c.into_inner();\n\nassert_eq!(five, 5);
\n
",0,"composable::views::gesture::State"],["
source§

impl<T> Cell<T>
where\n T: Copy,

1.0.0 · source

pub fn get(&self) -> T

Returns a copy of the contained value.

\n
§Examples
\n
use std::cell::Cell;\n\nlet c = Cell::new(5);\n\nlet five = c.get();
\n
source

pub fn update<F>(&self, f: F) -> T
where\n F: FnOnce(T) -> T,

🔬This is a nightly-only experimental API. (cell_update)

Updates the contained value using a function and returns the new value.

\n
§Examples
\n
#![feature(cell_update)]\n\nuse std::cell::Cell;\n\nlet c = Cell::new(5);\nlet new = c.update(|x| x + 1);\n\nassert_eq!(new, 6);\nassert_eq!(c.get(), 6);
\n
",0,"composable::views::gesture::State"],["
source§

impl<T> Cell<T>
where\n T: ?Sized,

1.12.0 (const: 1.32.0) · source

pub const fn as_ptr(&self) -> *mut T

Returns a raw pointer to the underlying data in this cell.

\n
§Examples
\n
use std::cell::Cell;\n\nlet c = Cell::new(5);\n\nlet ptr = c.as_ptr();
\n
1.11.0 · source

pub fn get_mut(&mut self) -> &mut T

Returns a mutable reference to the underlying data.

\n

This call borrows Cell mutably (at compile-time) which guarantees\nthat we possess the only reference.

\n

However be cautious: this method expects self to be mutable, which is\ngenerally not the case when using a Cell. If you require interior\nmutability by reference, consider using RefCell which provides\nrun-time checked mutable borrows through its borrow_mut method.

\n
§Examples
\n
use std::cell::Cell;\n\nlet mut c = Cell::new(5);\n*c.get_mut() += 1;\n\nassert_eq!(c.get(), 6);
\n
1.37.0 · source

pub fn from_mut(t: &mut T) -> &Cell<T>

Returns a &Cell<T> from a &mut T

\n
§Examples
\n
use std::cell::Cell;\n\nlet slice: &mut [i32] = &mut [1, 2, 3];\nlet cell_slice: &Cell<[i32]> = Cell::from_mut(slice);\nlet slice_cell: &[Cell<i32>] = cell_slice.as_slice_of_cells();\n\nassert_eq!(slice_cell.len(), 3);
\n
",0,"composable::views::gesture::State"],["
source§

impl<T> Cell<T>
where\n T: Default,

1.17.0 · source

pub fn take(&self) -> T

Takes the value of the cell, leaving Default::default() in its place.

\n
§Examples
\n
use std::cell::Cell;\n\nlet c = Cell::new(5);\nlet five = c.take();\n\nassert_eq!(five, 5);\nassert_eq!(c.into_inner(), 0);
\n
",0,"composable::views::gesture::State"],["
1.0.0 · source§

impl<T> Clone for Cell<T>
where\n T: Copy,

source§

fn clone(&self) -> Cell<T>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
","Clone","composable::views::gesture::State"],["
1.0.0 · source§

impl<T> Debug for Cell<T>
where\n T: Copy + Debug,

source§

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

Formats the value using the given formatter. Read more
","Debug","composable::views::gesture::State"],["
1.0.0 · source§

impl<T> Default for Cell<T>
where\n T: Default,

source§

fn default() -> Cell<T>

Creates a Cell<T>, with the Default value for T.

\n
","Default","composable::views::gesture::State"],["
1.12.0 · source§

impl<T> From<T> for Cell<T>

source§

fn from(t: T) -> Cell<T>

Creates a new Cell<T> containing the given value.

\n
","From","composable::views::gesture::State"],["
1.10.0 · source§

impl<T> Ord for Cell<T>
where\n T: Ord + Copy,

source§

fn cmp(&self, other: &Cell<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

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

Compares and returns the maximum of two values. Read more
1.21.0 · source§

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

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where\n Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
","Ord","composable::views::gesture::State"],["
1.0.0 · source§

impl<T> PartialEq for Cell<T>
where\n T: PartialEq + Copy,

source§

fn eq(&self, other: &Cell<T>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","composable::views::gesture::State"],["
1.10.0 · source§

impl<T> PartialOrd for Cell<T>
where\n T: PartialOrd + Copy,

source§

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

This method returns an ordering between self and other values if one exists. Read more
source§

fn lt(&self, other: &Cell<T>) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
source§

fn le(&self, other: &Cell<T>) -> bool

This method tests less than or equal to (for self and other) and is used by the <=\noperator. Read more
source§

fn gt(&self, other: &Cell<T>) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
source§

fn ge(&self, other: &Cell<T>) -> bool

This method tests greater than or equal to (for self and other) and is used by the >=\noperator. Read more
","PartialOrd","composable::views::gesture::State"],["
§

impl<T> Zeroable for Cell<T>
where\n T: Zeroable,

§

fn zeroed() -> Self

","Zeroable","composable::views::gesture::State"],["
source§

impl<T, U> CoerceUnsized<Cell<U>> for Cell<T>
where\n T: CoerceUnsized<U>,

","CoerceUnsized>","composable::views::gesture::State"],["
source§

impl<T: DependencyDefault> DependencyDefault for Cell<T>

","DependencyDefault","composable::views::gesture::State"],["
source§

impl<T, U> DispatchFromDyn<Cell<U>> for Cell<T>
where\n T: DispatchFromDyn<U>,

","DispatchFromDyn>","composable::views::gesture::State"],["
1.2.0 · source§

impl<T> Eq for Cell<T>
where\n T: Eq + Copy,

","Eq","composable::views::gesture::State"],["
1.0.0 · source§

impl<T> Send for Cell<T>
where\n T: Send + ?Sized,

","Send","composable::views::gesture::State"],["
1.0.0 · source§

impl<T> !Sync for Cell<T>
where\n T: ?Sized,

","Sync","composable::views::gesture::State"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/euclid/box2d/struct.Box2D.js b/type.impl/euclid/box2d/struct.Box2D.js new file mode 100644 index 00000000..55b947f0 --- /dev/null +++ b/type.impl/euclid/box2d/struct.Box2D.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"composable":[["
§

impl<T, U> Box2D<T, U>

pub const fn new(min: Point2D<T, U>, max: Point2D<T, U>) -> Box2D<T, U>

Constructor.

\n

pub fn from_origin_and_size(\n origin: Point2D<T, U>,\n size: Size2D<T, U>,\n) -> Box2D<T, U>
where\n T: Copy + Add<Output = T>,

Constructor.

\n

pub fn from_size(size: Size2D<T, U>) -> Box2D<T, U>
where\n T: Zero,

Creates a Box2D of the given size, at offset zero.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: PartialOrd,

pub fn is_negative(&self) -> bool

Returns true if the box has a negative area.

\n

The common interpretation for a negative box is to consider it empty. It can be obtained\nby calculating the intersection of two boxes that do not intersect.

\n

pub fn is_empty(&self) -> bool

Returns true if the size is zero, negative or NaN.

\n

pub fn intersects(&self, other: &Box2D<T, U>) -> bool

Returns true if the two boxes intersect.

\n

pub fn contains(&self, p: Point2D<T, U>) -> bool

Returns true if this box2d contains the point p. A point is considered\nin the box2d if it lies on the left or top edges, but outside if it lies\non the right or bottom edges.

\n

pub fn contains_inclusive(&self, p: Point2D<T, U>) -> bool

Returns true if this box contains the point p. A point is considered\nin the box2d if it lies on any edge of the box2d.

\n

pub fn contains_box(&self, other: &Box2D<T, U>) -> bool

Returns true if this box contains the interior of the other box. Always\nreturns true if other is empty, and always returns false if other is\nnonempty but this box is empty.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + PartialOrd,

pub fn to_non_empty(&self) -> Option<Box2D<T, U>>

pub fn intersection(&self, other: &Box2D<T, U>) -> Option<Box2D<T, U>>

Computes the intersection of two boxes, returning None if the boxes do not intersect.

\n

pub fn intersection_unchecked(&self, other: &Box2D<T, U>) -> Box2D<T, U>

Computes the intersection of two boxes without check whether they do intersect.

\n

The result is a negative box if the boxes do not intersect.\nThis can be useful for computing the intersection of more than two boxes, as\nit is possible to chain multiple intersection_unchecked calls and check for\nempty/negative result at the end.

\n

pub fn union(&self, other: &Box2D<T, U>) -> Box2D<T, U>

Computes the union of two boxes.

\n

If either of the boxes is empty, the other one is returned.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + Add<Output = T> + Sub<Output = T>,

pub fn inflate(&self, width: T, height: T) -> Box2D<T, U>

Inflates the box by the specified sizes on each side respectively.

\n

pub fn inner_box(&self, offsets: SideOffsets2D<T, U>) -> Box2D<T, U>

Calculate the size and position of an inner box.

\n

Subtracts the side offsets from all sides. The horizontal, vertical\nand applicate offsets must not be larger than the original side length.

\n

pub fn outer_box(&self, offsets: SideOffsets2D<T, U>) -> Box2D<T, U>

Calculate the b and position of an outer box.

\n

Add the offsets to all sides. The expanded box is returned.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + Add<Output = T>,

pub fn translate(&self, by: Vector2D<T, U>) -> Box2D<T, U>

Returns the same box, translated by a vector.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + Mul<Output = T> + Sub<Output = T>,

pub fn area(&self) -> T

",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + Sub<Output = T>,

pub fn size(&self) -> Size2D<T, U>

pub fn set_size(&mut self, size: Size2D<T, U>)

Change the size of the box by adjusting the max endpoint\nwithout modifying the min endpoint.

\n

pub fn width(&self) -> T

pub fn height(&self) -> T

pub fn to_rect(&self) -> Rect<T, U>

",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + One + Add<Output = T> + Div<Output = T>,

pub fn center(&self) -> Point2D<T, U>

",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy + Zero + PartialOrd,

pub fn from_points<I>(points: I) -> Box2D<T, U>
where\n I: IntoIterator,\n <I as IntoIterator>::Item: Borrow<Point2D<T, U>>,

Returns the smallest box containing all of the provided points.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Copy,

pub fn x_range(&self) -> Range<T>

pub fn y_range(&self) -> Range<T>

pub fn to_untyped(&self) -> Box2D<T, UnknownUnit>

Drop the units, preserving only the numeric value.

\n

pub fn from_untyped(c: &Box2D<T, UnknownUnit>) -> Box2D<T, U>

Tag a unitless value with units.

\n

pub fn cast_unit<V>(&self) -> Box2D<T, V>

Cast the unit

\n

pub fn scale<S>(&self, x: S, y: S) -> Box2D<T, U>
where\n S: Copy,\n T: Mul<S, Output = T>,

",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: NumCast + Copy,

pub fn cast<NewT>(&self) -> Box2D<NewT, U>
where\n NewT: NumCast,

Cast from one numeric representation to another, preserving the units.

\n

When casting from floating point to integer coordinates, the decimals are truncated\nas one would expect from a simple cast, but this behavior does not always make sense\ngeometrically. Consider using round(), round_in or round_out() before casting.

\n

pub fn try_cast<NewT>(&self) -> Option<Box2D<NewT, U>>
where\n NewT: NumCast,

Fallible cast from one numeric representation to another, preserving the units.

\n

When casting from floating point to integer coordinates, the decimals are truncated\nas one would expect from a simple cast, but this behavior does not always make sense\ngeometrically. Consider using round(), round_in or round_out() before casting.

\n

pub fn to_f32(&self) -> Box2D<f32, U>

Cast into an f32 box.

\n

pub fn to_f64(&self) -> Box2D<f64, U>

Cast into an f64 box.

\n

pub fn to_usize(&self) -> Box2D<usize, U>

Cast into an usize box, truncating decimals if any.

\n

When casting from floating point boxes, it is worth considering whether\nto round(), round_in() or round_out() before the cast in order to\nobtain the desired conversion behavior.

\n

pub fn to_u32(&self) -> Box2D<u32, U>

Cast into an u32 box, truncating decimals if any.

\n

When casting from floating point boxes, it is worth considering whether\nto round(), round_in() or round_out() before the cast in order to\nobtain the desired conversion behavior.

\n

pub fn to_i32(&self) -> Box2D<i32, U>

Cast into an i32 box, truncating decimals if any.

\n

When casting from floating point boxes, it is worth considering whether\nto round(), round_in() or round_out() before the cast in order to\nobtain the desired conversion behavior.

\n

pub fn to_i64(&self) -> Box2D<i64, U>

Cast into an i64 box, truncating decimals if any.

\n

When casting from floating point boxes, it is worth considering whether\nto round(), round_in() or round_out() before the cast in order to\nobtain the desired conversion behavior.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Float,

pub fn is_finite(self) -> bool

Returns true if all members are finite.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Floor + Ceil,

pub fn round_in(&self) -> Box2D<T, U>

Return a box with faces/edges rounded to integer coordinates, such that\nthe original box contains the resulting box.

\n

pub fn round_out(&self) -> Box2D<T, U>

Return a box with faces/edges rounded to integer coordinates, such that\nthe original box is contained in the resulting box.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: One + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Copy,

pub fn lerp(&self, other: Box2D<T, U>, t: T) -> Box2D<T, U>

Linearly interpolate between this box and another box.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Round,

pub fn round(&self) -> Box2D<T, U>

Return a box with edges rounded to integer coordinates, such that\nthe returned box has the same set of pixel centers as the original\none.\nValues equal to 0.5 round up.\nSuitable for most places where integral device coordinates\nare needed, but note that any translation should be applied first to\navoid pixel rounding errors.\nNote that this is not rounding to nearest integer if the values are negative.\nThey are always rounding as floor(n + 0.5).

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Box2D<T, U>
where\n T: Zero,

pub fn zero() -> Box2D<T, U>

Constructor, setting all sides to zero.

\n
",0,"composable::views::Bounds"],["
§

impl<T, U> Clone for Box2D<T, U>
where\n T: Clone,

§

fn clone(&self) -> Box2D<T, U>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
","Clone","composable::views::Bounds"],["
§

impl<T, U> Debug for Box2D<T, U>
where\n T: Debug,

§

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

Formats the value using the given formatter. Read more
","Debug","composable::views::Bounds"],["
§

impl<T, U> Default for Box2D<T, U>
where\n T: Default,

§

fn default() -> Box2D<T, U>

Returns the “default value” for a type. Read more
","Default","composable::views::Bounds"],["
§

impl<T, U1, U2> Div<Scale<T, U1, U2>> for Box2D<T, U2>
where\n T: Copy + Div,

§

type Output = Box2D<<T as Div>::Output, U1>

The resulting type after applying the / operator.
§

fn div(\n self,\n scale: Scale<T, U1, U2>,\n) -> <Box2D<T, U2> as Div<Scale<T, U1, U2>>>::Output

Performs the / operation. Read more
","Div>","composable::views::Bounds"],["
§

impl<T, U> Div<T> for Box2D<T, U>
where\n T: Copy + Div,

§

type Output = Box2D<<T as Div>::Output, U>

The resulting type after applying the / operator.
§

fn div(self, scale: T) -> <Box2D<T, U> as Div<T>>::Output

Performs the / operation. Read more
","Div","composable::views::Bounds"],["
§

impl<T, U> DivAssign<Scale<T, U, U>> for Box2D<T, U>
where\n T: Copy + DivAssign,

§

fn div_assign(&mut self, scale: Scale<T, U, U>)

Performs the /= operation. Read more
","DivAssign>","composable::views::Bounds"],["
§

impl<T, U> DivAssign<T> for Box2D<T, U>
where\n T: Copy + DivAssign,

§

fn div_assign(&mut self, scale: T)

Performs the /= operation. Read more
","DivAssign","composable::views::Bounds"],["
§

impl<T, U> From<Size2D<T, U>> for Box2D<T, U>
where\n T: Copy + Zero + PartialOrd,

§

fn from(b: Size2D<T, U>) -> Box2D<T, U>

Converts to this type from the input type.
","From>","composable::views::Bounds"],["
§

impl<T, U> Hash for Box2D<T, U>
where\n T: Hash,

§

fn hash<H>(&self, h: &mut H)
where\n H: Hasher,

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

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

Feeds a slice of this type into the given Hasher. Read more
","Hash","composable::views::Bounds"],["
§

impl<T, U1, U2> Mul<Scale<T, U1, U2>> for Box2D<T, U1>
where\n T: Copy + Mul,

§

type Output = Box2D<<T as Mul>::Output, U2>

The resulting type after applying the * operator.
§

fn mul(\n self,\n scale: Scale<T, U1, U2>,\n) -> <Box2D<T, U1> as Mul<Scale<T, U1, U2>>>::Output

Performs the * operation. Read more
","Mul>","composable::views::Bounds"],["
§

impl<T, U> Mul<T> for Box2D<T, U>
where\n T: Copy + Mul,

§

type Output = Box2D<<T as Mul>::Output, U>

The resulting type after applying the * operator.
§

fn mul(self, scale: T) -> <Box2D<T, U> as Mul<T>>::Output

Performs the * operation. Read more
","Mul","composable::views::Bounds"],["
§

impl<T, U> MulAssign<Scale<T, U, U>> for Box2D<T, U>
where\n T: Copy + MulAssign,

§

fn mul_assign(&mut self, scale: Scale<T, U, U>)

Performs the *= operation. Read more
","MulAssign>","composable::views::Bounds"],["
§

impl<T, U> MulAssign<T> for Box2D<T, U>
where\n T: Copy + MulAssign,

§

fn mul_assign(&mut self, scale: T)

Performs the *= operation. Read more
","MulAssign","composable::views::Bounds"],["
§

impl<T, U> PartialEq for Box2D<T, U>
where\n T: PartialEq,

§

fn eq(&self, other: &Box2D<T, U>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","composable::views::Bounds"],["
§

impl<T, U> Copy for Box2D<T, U>
where\n T: Copy,

","Copy","composable::views::Bounds"],["
§

impl<T, U> Eq for Box2D<T, U>
where\n T: Eq,

","Eq","composable::views::Bounds"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/euclid/default/type.SideOffsets2D.js b/type.impl/euclid/default/type.SideOffsets2D.js new file mode 100644 index 00000000..efc46ed2 --- /dev/null +++ b/type.impl/euclid/default/type.SideOffsets2D.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"composable":[] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/euclid/point/struct.Point2D.js b/type.impl/euclid/point/struct.Point2D.js new file mode 100644 index 00000000..cb73629c --- /dev/null +++ b/type.impl/euclid/point/struct.Point2D.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"composable":[["
§

impl<T, U> Add<Size2D<T, U>> for Point2D<T, U>
where\n T: Add,

§

type Output = Point2D<<T as Add>::Output, U>

The resulting type after applying the + operator.
§

fn add(\n self,\n other: Size2D<T, U>,\n) -> <Point2D<T, U> as Add<Size2D<T, U>>>::Output

Performs the + operation. Read more
","Add>","composable::views::Point"],["
§

impl<T, U> Add<Vector2D<T, U>> for Point2D<T, U>
where\n T: Add,

§

type Output = Point2D<<T as Add>::Output, U>

The resulting type after applying the + operator.
§

fn add(\n self,\n other: Vector2D<T, U>,\n) -> <Point2D<T, U> as Add<Vector2D<T, U>>>::Output

Performs the + operation. Read more
","Add>","composable::views::Point"],["
§

impl<T, U> AddAssign<Size2D<T, U>> for Point2D<T, U>
where\n T: AddAssign,

§

fn add_assign(&mut self, other: Size2D<T, U>)

Performs the += operation. Read more
","AddAssign>","composable::views::Point"],["
§

impl<T, U> AddAssign<Vector2D<T, U>> for Point2D<T, U>
where\n T: Copy + Add<Output = T>,

§

fn add_assign(&mut self, other: Vector2D<T, U>)

Performs the += operation. Read more
","AddAssign>","composable::views::Point"],["
§

impl<T, U> ApproxEq<Point2D<T, U>> for Point2D<T, U>
where\n T: ApproxEq<T>,

§

fn approx_epsilon() -> Point2D<T, U>

Default epsilon value
§

fn approx_eq_eps(&self, other: &Point2D<T, U>, eps: &Point2D<T, U>) -> bool

Returns true is this object is approximately equal to the other one, using\na provided epsilon value.
§

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

Returns true is this object is approximately equal to the other one, using\nthe approx_epsilon() epsilon value.
","ApproxEq>","composable::views::Point"],["
§

impl<T, U> Ceil for Point2D<T, U>
where\n T: Ceil,

§

fn ceil(self) -> Point2D<T, U>

","Ceil","composable::views::Point"],["
§

impl<T, U> Clone for Point2D<T, U>
where\n T: Clone,

§

fn clone(&self) -> Point2D<T, U>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
","Clone","composable::views::Point"],["
§

impl<T, U> Debug for Point2D<T, U>
where\n T: Debug,

§

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

Formats the value using the given formatter. Read more
","Debug","composable::views::Point"],["
§

impl<T, U> Default for Point2D<T, U>
where\n T: Default,

§

fn default() -> Point2D<T, U>

Returns the “default value” for a type. Read more
","Default","composable::views::Point"],["
§

impl<T, U1, U2> Div<Scale<T, U1, U2>> for Point2D<T, U2>
where\n T: Copy + Div,

§

type Output = Point2D<<T as Div>::Output, U1>

The resulting type after applying the / operator.
§

fn div(\n self,\n scale: Scale<T, U1, U2>,\n) -> <Point2D<T, U2> as Div<Scale<T, U1, U2>>>::Output

Performs the / operation. Read more
","Div>","composable::views::Point"],["
§

impl<T, U> Div<T> for Point2D<T, U>
where\n T: Copy + Div,

§

type Output = Point2D<<T as Div>::Output, U>

The resulting type after applying the / operator.
§

fn div(self, scale: T) -> <Point2D<T, U> as Div<T>>::Output

Performs the / operation. Read more
","Div","composable::views::Point"],["
§

impl<T, U> DivAssign<Scale<T, U, U>> for Point2D<T, U>
where\n T: Copy + DivAssign,

§

fn div_assign(&mut self, scale: Scale<T, U, U>)

Performs the /= operation. Read more
","DivAssign>","composable::views::Point"],["
§

impl<T, U> DivAssign<T> for Point2D<T, U>
where\n T: Copy + Div<Output = T>,

§

fn div_assign(&mut self, scale: T)

Performs the /= operation. Read more
","DivAssign","composable::views::Point"],["
§

impl<T, U> Floor for Point2D<T, U>
where\n T: Floor,

§

fn floor(self) -> Point2D<T, U>

","Floor","composable::views::Point"],["
§

impl<T, U> From<[T; 2]> for Point2D<T, U>

§

fn from(_: [T; 2]) -> Point2D<T, U>

Converts to this type from the input type.
","From<[T; 2]>","composable::views::Point"],["
§

impl<T, U> From<(T, T)> for Point2D<T, U>

§

fn from(tuple: (T, T)) -> Point2D<T, U>

Converts to this type from the input type.
","From<(T, T)>","composable::views::Point"],["
§

impl<T, U> Hash for Point2D<T, U>
where\n T: Hash,

§

fn hash<H>(&self, h: &mut H)
where\n H: Hasher,

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

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

Feeds a slice of this type into the given Hasher. Read more
","Hash","composable::views::Point"],["
§

impl<T, U1, U2> Mul<Scale<T, U1, U2>> for Point2D<T, U1>
where\n T: Copy + Mul,

§

type Output = Point2D<<T as Mul>::Output, U2>

The resulting type after applying the * operator.
§

fn mul(\n self,\n scale: Scale<T, U1, U2>,\n) -> <Point2D<T, U1> as Mul<Scale<T, U1, U2>>>::Output

Performs the * operation. Read more
","Mul>","composable::views::Point"],["
§

impl<T, U> Mul<T> for Point2D<T, U>
where\n T: Copy + Mul,

§

type Output = Point2D<<T as Mul>::Output, U>

The resulting type after applying the * operator.
§

fn mul(self, scale: T) -> <Point2D<T, U> as Mul<T>>::Output

Performs the * operation. Read more
","Mul","composable::views::Point"],["
§

impl<T, U> MulAssign<Scale<T, U, U>> for Point2D<T, U>
where\n T: Copy + MulAssign,

§

fn mul_assign(&mut self, scale: Scale<T, U, U>)

Performs the *= operation. Read more
","MulAssign>","composable::views::Point"],["
§

impl<T, U> MulAssign<T> for Point2D<T, U>
where\n T: Copy + Mul<Output = T>,

§

fn mul_assign(&mut self, scale: T)

Performs the *= operation. Read more
","MulAssign","composable::views::Point"],["
§

impl<T, U> Neg for Point2D<T, U>
where\n T: Neg,

§

type Output = Point2D<<T as Neg>::Output, U>

The resulting type after applying the - operator.
§

fn neg(self) -> <Point2D<T, U> as Neg>::Output

Performs the unary - operation. Read more
","Neg","composable::views::Point"],["
§

impl<T, U> PartialEq for Point2D<T, U>
where\n T: PartialEq,

§

fn eq(&self, other: &Point2D<T, U>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","composable::views::Point"],["
§

impl<T, U> Point2D<T, U>

pub fn origin() -> Point2D<T, U>
where\n T: Zero,

Constructor, setting all components to zero.

\n

pub fn zero() -> Point2D<T, U>
where\n T: Zero,

The same as origin().

\n

pub const fn new(x: T, y: T) -> Point2D<T, U>

Constructor taking scalar values directly.

\n

pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Point2D<T, U>

Constructor taking properly Lengths instead of scalar values.

\n

pub fn splat(v: T) -> Point2D<T, U>
where\n T: Clone,

Constructor setting all components to the same value.

\n

pub fn from_untyped(p: Point2D<T, UnknownUnit>) -> Point2D<T, U>

Tag a unitless value with units.

\n

pub fn map<V, F>(self, f: F) -> Point2D<V, U>
where\n F: FnMut(T) -> V,

Apply the function f to each component of this point.

\n
§Example
\n

This may be used to perform unusual arithmetic which is not already offered as methods.

\n\n
use euclid::default::Point2D;\n\nlet p = Point2D::<u32>::new(5, 15);\nassert_eq!(p.map(|coord| coord.saturating_sub(10)), Point2D::new(0, 5));
\n

pub fn zip<V, F>(self, rhs: Point2D<T, U>, f: F) -> Vector2D<V, U>
where\n F: FnMut(T, T) -> V,

Apply the function f to each pair of components of this point and rhs.

\n
§Example
\n

This may be used to perform unusual arithmetic which is not already offered as methods.

\n\n
use euclid::{default::{Point2D, Vector2D}, point2};\n\nlet a: Point2D<u32> = point2(50, 200);\nlet b: Point2D<u32> = point2(100, 100);\nassert_eq!(a.zip(b, u32::saturating_sub), Vector2D::new(0, 100));
\n
",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: PartialOrd,

pub fn min(self, other: Point2D<T, U>) -> Point2D<T, U>

pub fn max(self, other: Point2D<T, U>) -> Point2D<T, U>

pub fn clamp(self, start: Point2D<T, U>, end: Point2D<T, U>) -> Point2D<T, U>
where\n T: Copy,

Returns the point each component of which clamped by corresponding\ncomponents of start and end.

\n

Shortcut for self.max(start).min(end).

\n
",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: Copy + Add<Output = T>,

pub fn add_size(self, other: &Size2D<T, U>) -> Point2D<T, U>

",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: Copy,

pub fn extend(self, z: T) -> Point3D<T, U>

Create a 3d point from this one, using the specified z value.

\n

pub fn to_vector(self) -> Vector2D<T, U>

Cast this point into a vector.

\n

Equivalent to subtracting the origin from this point.

\n

pub fn yx(self) -> Point2D<T, U>

Swap x and y.

\n
§Example
\n
enum Mm {}\n\nlet point: Point2D<_, Mm> = point2(1, -8);\n\nassert_eq!(point.yx(), point2(-8, 1));
\n

pub fn to_untyped(self) -> Point2D<T, UnknownUnit>

Drop the units, preserving only the numeric value.

\n
§Example
\n
enum Mm {}\n\nlet point: Point2D<_, Mm> = point2(1, -8);\n\nassert_eq!(point.x, point.to_untyped().x);\nassert_eq!(point.y, point.to_untyped().y);
\n

pub fn cast_unit<V>(self) -> Point2D<T, V>

Cast the unit, preserving the numeric value.

\n
§Example
\n
enum Mm {}\nenum Cm {}\n\nlet point: Point2D<_, Mm> = point2(1, -8);\n\nassert_eq!(point.x, point.cast_unit::<Cm>().x);\nassert_eq!(point.y, point.cast_unit::<Cm>().y);
\n

pub fn to_array(self) -> [T; 2]

Cast into an array with x and y.

\n
§Example
\n
enum Mm {}\n\nlet point: Point2D<_, Mm> = point2(1, -8);\n\nassert_eq!(point.to_array(), [1, -8]);
\n

pub fn to_tuple(self) -> (T, T)

Cast into a tuple with x and y.

\n
§Example
\n
enum Mm {}\n\nlet point: Point2D<_, Mm> = point2(1, -8);\n\nassert_eq!(point.to_tuple(), (1, -8));
\n

pub fn to_3d(self) -> Point3D<T, U>
where\n T: Zero,

Convert into a 3d point with z-coordinate equals to zero.

\n

pub fn round(self) -> Point2D<T, U>
where\n T: Round,

Rounds each component to the nearest integer value.

\n

This behavior is preserved for negative values (unlike the basic cast).

\n\n
enum Mm {}\n\nassert_eq!(point2::<_, Mm>(-0.1, -0.8).round(), point2::<_, Mm>(0.0, -1.0))
\n

pub fn ceil(self) -> Point2D<T, U>
where\n T: Ceil,

Rounds each component to the smallest integer equal or greater than the original value.

\n

This behavior is preserved for negative values (unlike the basic cast).

\n\n
enum Mm {}\n\nassert_eq!(point2::<_, Mm>(-0.1, -0.8).ceil(), point2::<_, Mm>(0.0, 0.0))
\n

pub fn floor(self) -> Point2D<T, U>
where\n T: Floor,

Rounds each component to the biggest integer equal or lower than the original value.

\n

This behavior is preserved for negative values (unlike the basic cast).

\n\n
enum Mm {}\n\nassert_eq!(point2::<_, Mm>(-0.1, -0.8).floor(), point2::<_, Mm>(-1.0, -1.0))
\n

pub fn lerp(self, other: Point2D<T, U>, t: T) -> Point2D<T, U>
where\n T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,

Linearly interpolate between this point and another point.

\n
§Example
\n
use euclid::point2;\nuse euclid::default::Point2D;\n\nlet from: Point2D<_> = point2(0.0, 10.0);\nlet to:  Point2D<_> = point2(8.0, -4.0);\n\nassert_eq!(from.lerp(to, -1.0), point2(-8.0,  24.0));\nassert_eq!(from.lerp(to,  0.0), point2( 0.0,  10.0));\nassert_eq!(from.lerp(to,  0.5), point2( 4.0,   3.0));\nassert_eq!(from.lerp(to,  1.0), point2( 8.0,  -4.0));\nassert_eq!(from.lerp(to,  2.0), point2(16.0, -18.0));
\n
",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: NumCast + Copy,

pub fn cast<NewT>(self) -> Point2D<NewT, U>
where\n NewT: NumCast,

Cast from one numeric representation to another, preserving the units.

\n

When casting from floating point to integer coordinates, the decimals are truncated\nas one would expect from a simple cast, but this behavior does not always make sense\ngeometrically. Consider using round(), ceil() or floor() before casting.

\n

pub fn try_cast<NewT>(self) -> Option<Point2D<NewT, U>>
where\n NewT: NumCast,

Fallible cast from one numeric representation to another, preserving the units.

\n

When casting from floating point to integer coordinates, the decimals are truncated\nas one would expect from a simple cast, but this behavior does not always make sense\ngeometrically. Consider using round(), ceil() or floor() before casting.

\n

pub fn to_f32(self) -> Point2D<f32, U>

Cast into an f32 point.

\n

pub fn to_f64(self) -> Point2D<f64, U>

Cast into an f64 point.

\n

pub fn to_usize(self) -> Point2D<usize, U>

Cast into an usize point, truncating decimals if any.

\n

When casting from floating point points, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_u32(self) -> Point2D<u32, U>

Cast into an u32 point, truncating decimals if any.

\n

When casting from floating point points, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_i32(self) -> Point2D<i32, U>

Cast into an i32 point, truncating decimals if any.

\n

When casting from floating point points, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_i64(self) -> Point2D<i64, U>

Cast into an i64 point, truncating decimals if any.

\n

When casting from floating point points, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n
",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: Float,

pub fn is_finite(self) -> bool

Returns true if all members are finite.

\n
",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: Euclid,

pub fn rem_euclid(&self, other: &Size2D<T, U>) -> Point2D<T, U>

Calculates the least nonnegative remainder of self (mod other).

\n
§Example
\n
use euclid::point2;\nuse euclid::default::{Point2D, Size2D};\n\nlet p = Point2D::new(7.0, -7.0);\nlet s = Size2D::new(4.0, -4.0);\n\nassert_eq!(p.rem_euclid(&s), point2(3.0, 1.0));\nassert_eq!((-p).rem_euclid(&s), point2(1.0, 3.0));\nassert_eq!(p.rem_euclid(&-s), point2(3.0, 1.0));
\n

pub fn div_euclid(&self, other: &Size2D<T, U>) -> Point2D<T, U>

Calculates Euclidean division, the matching method for rem_euclid.

\n
§Example
\n
use euclid::point2;\nuse euclid::default::{Point2D, Size2D};\n\nlet p = Point2D::new(7.0, -7.0);\nlet s = Size2D::new(4.0, -4.0);\n\nassert_eq!(p.div_euclid(&s), point2(1.0, 2.0));\nassert_eq!((-p).div_euclid(&s), point2(-2.0, -1.0));\nassert_eq!(p.div_euclid(&-s), point2(-1.0, -2.0));
\n
",0,"composable::views::Point"],["
§

impl<T, U> Point2D<T, U>
where\n T: Real<Output = T> + Sub,

pub fn distance_to(self, other: Point2D<T, U>) -> T

",0,"composable::views::Point"],["
§

impl<U> Position for Point2D<f32, U>

§

fn position(&self) -> Point2D<f32, UnknownUnit>

","Position","composable::views::Point"],["
§

impl<T, U> Round for Point2D<T, U>
where\n T: Round,

§

fn round(self) -> Point2D<T, U>

","Round","composable::views::Point"],["
§

impl<T, U> Sub<Size2D<T, U>> for Point2D<T, U>
where\n T: Sub,

§

type Output = Point2D<<T as Sub>::Output, U>

The resulting type after applying the - operator.
§

fn sub(\n self,\n other: Size2D<T, U>,\n) -> <Point2D<T, U> as Sub<Size2D<T, U>>>::Output

Performs the - operation. Read more
","Sub>","composable::views::Point"],["
§

impl<T, U> Sub<Vector2D<T, U>> for Point2D<T, U>
where\n T: Sub,

§

type Output = Point2D<<T as Sub>::Output, U>

The resulting type after applying the - operator.
§

fn sub(\n self,\n other: Vector2D<T, U>,\n) -> <Point2D<T, U> as Sub<Vector2D<T, U>>>::Output

Performs the - operation. Read more
","Sub>","composable::views::Point"],["
§

impl<T, U> Sub for Point2D<T, U>
where\n T: Sub,

§

type Output = Vector2D<<T as Sub>::Output, U>

The resulting type after applying the - operator.
§

fn sub(self, other: Point2D<T, U>) -> <Point2D<T, U> as Sub>::Output

Performs the - operation. Read more
","Sub","composable::views::Point"],["
§

impl<T, U> SubAssign<Size2D<T, U>> for Point2D<T, U>
where\n T: SubAssign,

§

fn sub_assign(&mut self, other: Size2D<T, U>)

Performs the -= operation. Read more
","SubAssign>","composable::views::Point"],["
§

impl<T, U> SubAssign<Vector2D<T, U>> for Point2D<T, U>
where\n T: Copy + Sub<Output = T>,

§

fn sub_assign(&mut self, other: Vector2D<T, U>)

Performs the -= operation. Read more
","SubAssign>","composable::views::Point"],["
§

impl<T, U> Zero for Point2D<T, U>
where\n T: Zero,

§

fn zero() -> Point2D<T, U>

","Zero","composable::views::Point"],["
§

impl<T, U> Copy for Point2D<T, U>
where\n T: Copy,

","Copy","composable::views::Point"],["
§

impl<T, U> Eq for Point2D<T, U>
where\n T: Eq,

","Eq","composable::views::Point"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/euclid/size/struct.Size2D.js b/type.impl/euclid/size/struct.Size2D.js new file mode 100644 index 00000000..f64015dc --- /dev/null +++ b/type.impl/euclid/size/struct.Size2D.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"composable":[["
§

impl<T, U> Add<&Size2D<T, U>> for Size2D<T, U>
where\n T: Copy + Add<Output = T>,

§

type Output = Size2D<T, U>

The resulting type after applying the + operator.
§

fn add(self, other: &Size2D<T, U>) -> Size2D<T, U>

Performs the + operation. Read more
","Add<&Size2D>","composable::views::Size"],["
§

impl<T, U> Add for Size2D<T, U>
where\n T: Add,

§

type Output = Size2D<<T as Add>::Output, U>

The resulting type after applying the + operator.
§

fn add(self, other: Size2D<T, U>) -> <Size2D<T, U> as Add>::Output

Performs the + operation. Read more
","Add","composable::views::Size"],["
§

impl<T, U> AddAssign for Size2D<T, U>
where\n T: AddAssign,

§

fn add_assign(&mut self, other: Size2D<T, U>)

Performs the += operation. Read more
","AddAssign","composable::views::Size"],["
§

impl<T, U> Ceil for Size2D<T, U>
where\n T: Ceil,

§

fn ceil(self) -> Size2D<T, U>

","Ceil","composable::views::Size"],["
§

impl<T, U> Clone for Size2D<T, U>
where\n T: Clone,

§

fn clone(&self) -> Size2D<T, U>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
","Clone","composable::views::Size"],["
§

impl<T, U> Debug for Size2D<T, U>
where\n T: Debug,

§

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

Formats the value using the given formatter. Read more
","Debug","composable::views::Size"],["
§

impl<T, U> Default for Size2D<T, U>
where\n T: Default,

§

fn default() -> Size2D<T, U>

Returns the “default value” for a type. Read more
","Default","composable::views::Size"],["
§

impl<T, U1, U2> Div<Scale<T, U1, U2>> for Size2D<T, U2>
where\n T: Copy + Div,

§

type Output = Size2D<<T as Div>::Output, U1>

The resulting type after applying the / operator.
§

fn div(\n self,\n scale: Scale<T, U1, U2>,\n) -> <Size2D<T, U2> as Div<Scale<T, U1, U2>>>::Output

Performs the / operation. Read more
","Div>","composable::views::Size"],["
§

impl<T, U> Div<T> for Size2D<T, U>
where\n T: Copy + Div,

§

type Output = Size2D<<T as Div>::Output, U>

The resulting type after applying the / operator.
§

fn div(self, scale: T) -> <Size2D<T, U> as Div<T>>::Output

Performs the / operation. Read more
","Div","composable::views::Size"],["
§

impl<T, U> DivAssign<Scale<T, U, U>> for Size2D<T, U>
where\n T: Copy + DivAssign,

§

fn div_assign(&mut self, other: Scale<T, U, U>)

Performs the /= operation. Read more
","DivAssign>","composable::views::Size"],["
§

impl<T, U> DivAssign<T> for Size2D<T, U>
where\n T: Copy + DivAssign,

§

fn div_assign(&mut self, other: T)

Performs the /= operation. Read more
","DivAssign","composable::views::Size"],["
§

impl<T, U> Floor for Size2D<T, U>
where\n T: Floor,

§

fn floor(self) -> Size2D<T, U>

","Floor","composable::views::Size"],["
§

impl<T, U> From<[T; 2]> for Size2D<T, U>

§

fn from(_: [T; 2]) -> Size2D<T, U>

Converts to this type from the input type.
","From<[T; 2]>","composable::views::Size"],["
§

impl<T, U> From<(T, T)> for Size2D<T, U>

§

fn from(tuple: (T, T)) -> Size2D<T, U>

Converts to this type from the input type.
","From<(T, T)>","composable::views::Size"],["
§

impl<T, U> From<Vector2D<T, U>> for Size2D<T, U>

§

fn from(v: Vector2D<T, U>) -> Size2D<T, U>

Converts to this type from the input type.
","From>","composable::views::Size"],["
§

impl<T, U> Hash for Size2D<T, U>
where\n T: Hash,

§

fn hash<H>(&self, h: &mut H)
where\n H: Hasher,

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

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

Feeds a slice of this type into the given Hasher. Read more
","Hash","composable::views::Size"],["
§

impl<T, U1, U2> Mul<Scale<T, U1, U2>> for Size2D<T, U1>
where\n T: Copy + Mul,

§

type Output = Size2D<<T as Mul>::Output, U2>

The resulting type after applying the * operator.
§

fn mul(\n self,\n scale: Scale<T, U1, U2>,\n) -> <Size2D<T, U1> as Mul<Scale<T, U1, U2>>>::Output

Performs the * operation. Read more
","Mul>","composable::views::Size"],["
§

impl<T, U> Mul<T> for Size2D<T, U>
where\n T: Copy + Mul,

§

type Output = Size2D<<T as Mul>::Output, U>

The resulting type after applying the * operator.
§

fn mul(self, scale: T) -> <Size2D<T, U> as Mul<T>>::Output

Performs the * operation. Read more
","Mul","composable::views::Size"],["
§

impl<T, U> MulAssign<Scale<T, U, U>> for Size2D<T, U>
where\n T: Copy + MulAssign,

§

fn mul_assign(&mut self, other: Scale<T, U, U>)

Performs the *= operation. Read more
","MulAssign>","composable::views::Size"],["
§

impl<T, U> MulAssign<T> for Size2D<T, U>
where\n T: Copy + MulAssign,

§

fn mul_assign(&mut self, other: T)

Performs the *= operation. Read more
","MulAssign","composable::views::Size"],["
§

impl<T, U> Neg for Size2D<T, U>
where\n T: Neg,

§

type Output = Size2D<<T as Neg>::Output, U>

The resulting type after applying the - operator.
§

fn neg(self) -> <Size2D<T, U> as Neg>::Output

Performs the unary - operation. Read more
","Neg","composable::views::Size"],["
§

impl<T, U> PartialEq for Size2D<T, U>
where\n T: PartialEq,

§

fn eq(&self, other: &Size2D<T, U>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","composable::views::Size"],["
§

impl<T, U> Round for Size2D<T, U>
where\n T: Round,

§

fn round(self) -> Size2D<T, U>

","Round","composable::views::Size"],["
§

impl<T, U> Size2D<T, U>

pub fn zero() -> Size2D<T, U>
where\n T: Zero,

The same as Zero::zero() but available without importing trait.

\n

pub const fn new(width: T, height: T) -> Size2D<T, U>

Constructor taking scalar values.

\n

pub fn from_lengths(width: Length<T, U>, height: Length<T, U>) -> Size2D<T, U>

Constructor taking scalar strongly typed lengths.

\n

pub fn splat(v: T) -> Size2D<T, U>
where\n T: Clone,

Constructor setting all components to the same value.

\n

pub fn from_untyped(p: Size2D<T, UnknownUnit>) -> Size2D<T, U>

Tag a unitless value with units.

\n
",0,"composable::views::Size"],["
§

impl<T, U> Size2D<T, U>
where\n T: PartialEq,

pub fn equal(self, other: Size2D<T, U>) -> BoolVector2D

Returns vector with results of “equal” operation on each component.

\n

pub fn not_equal(self, other: Size2D<T, U>) -> BoolVector2D

Returns vector with results of “not equal” operation on each component.

\n
",0,"composable::views::Size"],["
§

impl<T, U> Size2D<T, U>
where\n T: PartialOrd,

pub fn min(self, other: Size2D<T, U>) -> Size2D<T, U>

Returns the size each component of which are minimum of this size and another.

\n

pub fn max(self, other: Size2D<T, U>) -> Size2D<T, U>

Returns the size each component of which are maximum of this size and another.

\n

pub fn clamp(self, start: Size2D<T, U>, end: Size2D<T, U>) -> Size2D<T, U>
where\n T: Copy,

Returns the size each component of which clamped by corresponding\ncomponents of start and end.

\n

Shortcut for self.max(start).min(end).

\n

pub fn contains(self, other: Size2D<T, U>) -> bool

pub fn greater_than(self, other: Size2D<T, U>) -> BoolVector2D

Returns vector with results of “greater then” operation on each component.

\n

pub fn lower_than(self, other: Size2D<T, U>) -> BoolVector2D

Returns vector with results of “lower then” operation on each component.

\n

pub fn is_empty(self) -> bool
where\n T: Zero,

Returns true if any component of size is zero, negative, or NaN.

\n
",0,"composable::views::Size"],["
§

impl<T, U> Size2D<T, U>
where\n T: Copy,

pub fn to_array(self) -> [T; 2]

Return this size as an array of two elements (width, then height).

\n

pub fn to_tuple(self) -> (T, T)

Return this size as a tuple of two elements (width, then height).

\n

pub fn to_vector(self) -> Vector2D<T, U>

Return this size as a vector with width and height.

\n

pub fn to_untyped(self) -> Size2D<T, UnknownUnit>

Drop the units, preserving only the numeric value.

\n

pub fn cast_unit<V>(self) -> Size2D<T, V>

Cast the unit

\n

pub fn round(self) -> Size2D<T, U>
where\n T: Round,

Rounds each component to the nearest integer value.

\n

This behavior is preserved for negative values (unlike the basic cast).

\n\n
enum Mm {}\n\nassert_eq!(size2::<_, Mm>(-0.1, -0.8).round(), size2::<_, Mm>(0.0, -1.0))
\n

pub fn ceil(self) -> Size2D<T, U>
where\n T: Ceil,

Rounds each component to the smallest integer equal or greater than the original value.

\n

This behavior is preserved for negative values (unlike the basic cast).

\n\n
enum Mm {}\n\nassert_eq!(size2::<_, Mm>(-0.1, -0.8).ceil(), size2::<_, Mm>(0.0, 0.0))
\n

pub fn floor(self) -> Size2D<T, U>
where\n T: Floor,

Rounds each component to the biggest integer equal or lower than the original value.

\n

This behavior is preserved for negative values (unlike the basic cast).

\n\n
enum Mm {}\n\nassert_eq!(size2::<_, Mm>(-0.1, -0.8).floor(), size2::<_, Mm>(-1.0, -1.0))
\n

pub fn area(self) -> <T as Mul>::Output
where\n T: Mul,

Returns result of multiplication of both components

\n

pub fn lerp(self, other: Size2D<T, U>, t: T) -> Size2D<T, U>
where\n T: One + Sub<Output = T> + Mul<Output = T> + Add<Output = T>,

Linearly interpolate each component between this size and another size.

\n
§Example
\n
use euclid::size2;\nuse euclid::default::Size2D;\n\nlet from: Size2D<_> = size2(0.0, 10.0);\nlet to:  Size2D<_> = size2(8.0, -4.0);\n\nassert_eq!(from.lerp(to, -1.0), size2(-8.0,  24.0));\nassert_eq!(from.lerp(to,  0.0), size2( 0.0,  10.0));\nassert_eq!(from.lerp(to,  0.5), size2( 4.0,   3.0));\nassert_eq!(from.lerp(to,  1.0), size2( 8.0,  -4.0));\nassert_eq!(from.lerp(to,  2.0), size2(16.0, -18.0));
\n
",0,"composable::views::Size"],["
§

impl<T, U> Size2D<T, U>
where\n T: NumCast + Copy,

pub fn cast<NewT>(self) -> Size2D<NewT, U>
where\n NewT: NumCast,

Cast from one numeric representation to another, preserving the units.

\n

When casting from floating point to integer coordinates, the decimals are truncated\nas one would expect from a simple cast, but this behavior does not always make sense\ngeometrically. Consider using round(), ceil() or floor() before casting.

\n

pub fn try_cast<NewT>(self) -> Option<Size2D<NewT, U>>
where\n NewT: NumCast,

Fallible cast from one numeric representation to another, preserving the units.

\n

When casting from floating point to integer coordinates, the decimals are truncated\nas one would expect from a simple cast, but this behavior does not always make sense\ngeometrically. Consider using round(), ceil() or floor() before casting.

\n

pub fn to_f32(self) -> Size2D<f32, U>

Cast into an f32 size.

\n

pub fn to_f64(self) -> Size2D<f64, U>

Cast into an f64 size.

\n

pub fn to_usize(self) -> Size2D<usize, U>

Cast into an uint size, truncating decimals if any.

\n

When casting from floating point sizes, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_u32(self) -> Size2D<u32, U>

Cast into an u32 size, truncating decimals if any.

\n

When casting from floating point sizes, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_u64(self) -> Size2D<u64, U>

Cast into an u64 size, truncating decimals if any.

\n

When casting from floating point sizes, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_i32(self) -> Size2D<i32, U>

Cast into an i32 size, truncating decimals if any.

\n

When casting from floating point sizes, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n

pub fn to_i64(self) -> Size2D<i64, U>

Cast into an i64 size, truncating decimals if any.

\n

When casting from floating point sizes, it is worth considering whether\nto round(), ceil() or floor() before the cast in order to obtain\nthe desired conversion behavior.

\n
",0,"composable::views::Size"],["
§

impl<T, U> Size2D<T, U>
where\n T: Float,

pub fn is_finite(self) -> bool

Returns true if all members are finite.

\n
",0,"composable::views::Size"],["
§

impl<T, U> Size2D<T, U>
where\n T: Signed,

pub fn abs(self) -> Size2D<T, U>

Computes the absolute value of each component.

\n

For f32 and f64, NaN will be returned for component if the component is NaN.

\n

For signed integers, ::MIN will be returned for component if the component is ::MIN.

\n

pub fn is_positive(self) -> bool

Returns true if both components is positive and false any component is zero or negative.

\n
",0,"composable::views::Size"],["
§

impl<T, U> Sub for Size2D<T, U>
where\n T: Sub,

§

type Output = Size2D<<T as Sub>::Output, U>

The resulting type after applying the - operator.
§

fn sub(self, other: Size2D<T, U>) -> <Size2D<T, U> as Sub>::Output

Performs the - operation. Read more
","Sub","composable::views::Size"],["
§

impl<T, U> SubAssign for Size2D<T, U>
where\n T: SubAssign,

§

fn sub_assign(&mut self, other: Size2D<T, U>)

Performs the -= operation. Read more
","SubAssign","composable::views::Size"],["
§

impl<'a, T, U> Sum<&'a Size2D<T, U>> for Size2D<T, U>
where\n T: 'a + Add<Output = T> + Copy + Zero,\n U: 'a,

§

fn sum<I>(iter: I) -> Size2D<T, U>
where\n I: Iterator<Item = &'a Size2D<T, U>>,

Method which takes an iterator and generates Self from the elements by\n“summing up” the items.
","Sum<&'a Size2D>","composable::views::Size"],["
§

impl<T, U> Sum for Size2D<T, U>
where\n T: Add<Output = T> + Zero,

§

fn sum<I>(iter: I) -> Size2D<T, U>
where\n I: Iterator<Item = Size2D<T, U>>,

Method which takes an iterator and generates Self from the elements by\n“summing up” the items.
","Sum","composable::views::Size"],["
§

impl<T, U> Zero for Size2D<T, U>
where\n T: Zero,

§

fn zero() -> Size2D<T, U>

","Zero","composable::views::Size"],["
§

impl<T, U> Copy for Size2D<T, U>
where\n T: Copy,

","Copy","composable::views::Size"],["
§

impl<T, U> Eq for Size2D<T, U>
where\n T: Eq,

","Eq","composable::views::Size"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/euclid/transform2d/struct.Transform2D.js b/type.impl/euclid/transform2d/struct.Transform2D.js new file mode 100644 index 00000000..15bfd3a9 --- /dev/null +++ b/type.impl/euclid/transform2d/struct.Transform2D.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"composable":[["
§

impl<T, Src, Dst> ApproxEq<T> for Transform2D<T, Src, Dst>
where\n T: ApproxEq<T>,

§

fn approx_eq_eps(&self, other: &Transform2D<T, Src, Dst>, eps: &T) -> bool

Returns true is this transform is approximately equal to the other one, using\na provided epsilon value.

\n
§

fn approx_epsilon() -> T

Default epsilon value
§

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

Returns true is this object is approximately equal to the other one, using\nthe approx_epsilon() epsilon value.
","ApproxEq","composable::views::Transform"],["
§

impl<T, Src, Dst> Clone for Transform2D<T, Src, Dst>
where\n T: Clone,

§

fn clone(&self) -> Transform2D<T, Src, Dst>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
","Clone","composable::views::Transform"],["
§

impl<T, Src, Dst> Debug for Transform2D<T, Src, Dst>
where\n T: Copy + Debug + PartialEq + One + Zero,

§

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

Formats the value using the given formatter. Read more
","Debug","composable::views::Transform"],["
§

impl<T, Src, Dst> Default for Transform2D<T, Src, Dst>
where\n T: Zero + One,

§

fn default() -> Transform2D<T, Src, Dst>

Returns the identity transform.

\n
","Default","composable::views::Transform"],["
§

impl<T, Src, Dst> From<Translation2D<T, Src, Dst>> for Transform2D<T, Src, Dst>
where\n T: Zero + One,

§

fn from(t: Translation2D<T, Src, Dst>) -> Transform2D<T, Src, Dst>

Converts to this type from the input type.
","From>","composable::views::Transform"],["
§

impl<T, Src, Dst> Hash for Transform2D<T, Src, Dst>
where\n T: Hash,

§

fn hash<H>(&self, h: &mut H)
where\n H: Hasher,

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

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

Feeds a slice of this type into the given Hasher. Read more
","Hash","composable::views::Transform"],["
§

impl<T, Src, Dst> PartialEq for Transform2D<T, Src, Dst>
where\n T: PartialEq,

§

fn eq(&self, other: &Transform2D<T, Src, Dst>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>

Methods for creating and combining scale transformations

\n

pub fn scale(x: T, y: T) -> Transform2D<T, Src, Dst>
where\n T: Zero,

Create a 2d scale transform:

\n
x 0\n0 y\n0 0\n

pub fn then_scale(&self, x: T, y: T) -> Transform2D<T, Src, Dst>
where\n T: Copy + Add<Output = T> + Mul<Output = T> + Zero,

Applies a scale after self’s transformation and returns the resulting transform.

\n

pub fn pre_scale(&self, x: T, y: T) -> Transform2D<T, Src, Dst>
where\n T: Copy + Mul<Output = T>,

Applies a scale before self’s transformation and returns the resulting transform.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>

pub const fn new(\n m11: T,\n m12: T,\n m21: T,\n m22: T,\n m31: T,\n m32: T,\n) -> Transform2D<T, Src, Dst>

Create a transform specifying its components in using the column-major-column-vector\nmatrix notation.

\n

For example, the translation terms m31 and m32 are the last two parameters parameters.

\n\n
use euclid::default::Transform2D;\nlet tx = 1.0;\nlet ty = 2.0;\nlet translation = Transform2D::new(\n  1.0, 0.0,\n  0.0, 1.0,\n  tx,  ty,\n);
\n

pub fn approx_eq(&self, other: &Transform2D<T, Src, Dst>) -> bool
where\n T: ApproxEq<T>,

Returns true is this transform is approximately equal to the other one, using\nT’s default epsilon value.

\n

The same as ApproxEq::approx_eq() but available without importing trait.

\n

pub fn approx_eq_eps(&self, other: &Transform2D<T, Src, Dst>, eps: &T) -> bool
where\n T: ApproxEq<T>,

Returns true is this transform is approximately equal to the other one, using\na provided epsilon value.

\n

The same as ApproxEq::approx_eq_eps() but available without importing trait.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Copy + Add<Output = T> + Mul<Output = T>,

Methods for apply transformations to objects

\n

pub fn transform_point(&self, point: Point2D<T, Src>) -> Point2D<T, Dst>

Returns the given point transformed by this transform.

\n

pub fn transform_vector(&self, vec: Vector2D<T, Src>) -> Vector2D<T, Dst>

Returns the given vector transformed by this matrix.

\n

pub fn outer_transformed_rect(&self, rect: &Rect<T, Src>) -> Rect<T, Dst>
where\n T: Sub<Output = T> + Zero + PartialOrd,

Returns a rectangle that encompasses the result of transforming the given rectangle by this\ntransform.

\n

pub fn outer_transformed_box(&self, b: &Box2D<T, Src>) -> Box2D<T, Dst>
where\n T: Sub<Output = T> + Zero + PartialOrd,

Returns a box that encompasses the result of transforming the given box by this\ntransform.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Copy + Add<Output = T> + Mul<Output = T>,

Methods for combining generic transformations

\n

pub fn then<NewDst>(\n &self,\n mat: &Transform2D<T, Dst, NewDst>,\n) -> Transform2D<T, Src, NewDst>

Returns the multiplication of the two matrices such that mat’s transformation\napplies after self’s transformation.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Copy + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + Zero + Trig,

Methods for creating and combining rotation transformations

\n

pub fn rotation(theta: Angle<T>) -> Transform2D<T, Src, Dst>

Returns a rotation transform.

\n

pub fn then_rotate(&self, theta: Angle<T>) -> Transform2D<T, Src, Dst>

Applies a rotation after self’s transformation and returns the resulting transform.

\n

pub fn pre_rotate(&self, theta: Angle<T>) -> Transform2D<T, Src, Dst>

Applies a rotation before self’s transformation and returns the resulting transform.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Copy + Sub<Output = T> + Mul<Output = T> + Div<Output = T> + PartialEq + Zero + One,

pub fn determinant(&self) -> T

Computes and returns the determinant of this transform.

\n

pub fn is_invertible(&self) -> bool

Returns whether it is possible to compute the inverse transform.

\n

pub fn inverse(&self) -> Option<Transform2D<T, Dst, Src>>

Returns the inverse transform if possible.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Copy,

pub fn to_array(&self) -> [T; 6]

Returns an array containing this transform’s terms.

\n

The terms are laid out in the same order as they are\nspecified in Transform2D::new, that is following the\ncolumn-major-column-vector matrix notation.

\n

For example the translation terms are found in the\nlast two slots of the array.

\n

pub fn to_array_transposed(&self) -> [T; 6]

Returns an array containing this transform’s terms transposed.

\n

The terms are laid out in transposed order from the same order of\nTransform3D::new and Transform3D::to_array, that is following\nthe row-major-column-vector matrix notation.

\n

For example the translation terms are found at indices 2 and 5\nin the array.

\n

pub fn to_arrays(&self) -> [[T; 2]; 3]

Equivalent to to_array with elements packed two at a time\nin an array of arrays.

\n

pub fn from_array(array: [T; 6]) -> Transform2D<T, Src, Dst>

Create a transform providing its components via an array\nof 6 elements instead of as individual parameters.

\n

The order of the components corresponds to the\ncolumn-major-column-vector matrix notation (the same order\nas Transform2D::new).

\n

pub fn from_arrays(array: [[T; 2]; 3]) -> Transform2D<T, Src, Dst>

Equivalent to from_array with elements packed two at a time\nin an array of arrays.

\n

The order of the components corresponds to the\ncolumn-major-column-vector matrix notation (the same order\nas Transform3D::new).

\n

pub fn to_untyped(&self) -> Transform2D<T, UnknownUnit, UnknownUnit>

Drop the units, preserving only the numeric value.

\n

pub fn from_untyped(\n p: &Transform2D<T, UnknownUnit, UnknownUnit>,\n) -> Transform2D<T, Src, Dst>

Tag a unitless value with units.

\n

pub fn with_source<NewSrc>(&self) -> Transform2D<T, NewSrc, Dst>

Returns the same transform with a different source unit.

\n

pub fn with_destination<NewDst>(&self) -> Transform2D<T, Src, NewDst>

Returns the same transform with a different destination unit.

\n

pub fn to_3d(&self) -> Transform3D<T, Src, Dst>
where\n T: Zero + One,

Create a 3D transform from the current transform

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: NumCast + Copy,

pub fn cast<NewT>(&self) -> Transform2D<NewT, Src, Dst>
where\n NewT: NumCast,

Cast from one numeric representation to another, preserving the units.

\n

pub fn try_cast<NewT>(&self) -> Option<Transform2D<NewT, Src, Dst>>
where\n NewT: NumCast,

Fallible cast from one numeric representation to another, preserving the units.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Zero + One,

Methods for creating and combining translation transformations

\n

pub fn translation(x: T, y: T) -> Transform2D<T, Src, Dst>

Create a 2d translation transform:

\n
1 0\n0 1\nx y\n

pub fn then_translate(&self, v: Vector2D<T, Dst>) -> Transform2D<T, Src, Dst>
where\n T: Copy + Add<Output = T> + Mul<Output = T>,

Applies a translation after self’s transformation and returns the resulting transform.

\n

pub fn pre_translate(&self, v: Vector2D<T, Src>) -> Transform2D<T, Src, Dst>
where\n T: Copy + Add<Output = T> + Mul<Output = T>,

Applies a translation before self’s transformation and returns the resulting transform.

\n
",0,"composable::views::Transform"],["
§

impl<T, Src, Dst> Transform2D<T, Src, Dst>
where\n T: Zero + One,

pub fn identity() -> Transform2D<T, Src, Dst>

Create an identity matrix:

\n
1 0\n0 1\n0 0\n
",0,"composable::views::Transform"],["
§

impl<S> Transformation<S> for Transform2D<S, UnknownUnit, UnknownUnit>
where\n S: Scalar,

§

fn transform_point(&self, p: Point2D<S, UnknownUnit>) -> Point2D<S, UnknownUnit>

§

fn transform_vector(\n &self,\n v: Vector2D<S, UnknownUnit>,\n) -> Vector2D<S, UnknownUnit>

","Transformation","composable::views::Transform"],["
§

impl<T, Src, Dst> Copy for Transform2D<T, Src, Dst>
where\n T: Copy,

","Copy","composable::views::Transform"],["
§

impl<T, Src, Dst> Eq for Transform2D<T, Src, Dst>
where\n T: Eq,

","Eq","composable::views::Transform"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file