Struct std::any::Demand

source ·
#[repr(transparent)]
pub struct Demand<'a>(dyn Erased<'a>);
🔬This is a nightly-only experimental API. (provide_any #96024)
Expand description

A helper object for providing data by type.

A data provider provides values by calling this type’s provide methods.

Tuple Fields§

§0: dyn Erased<'a>
🔬This is a nightly-only experimental API. (provide_any #96024)

Implementations§

source§

impl<'a> Demand<'a>

source

pub fn provide_value<T>(&mut self, value: T) -> &mut Demand<'a>where T: 'static,

🔬This is a nightly-only experimental API. (provide_any #96024)

Provide a value or other type with only static lifetimes.

Examples

Provides an u8.

#![feature(provide_any)]

use std::any::{Provider, Demand};

impl Provider for SomeConcreteType {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        demand.provide_value::<u8>(self.field);
    }
}
Run
source

pub fn provide_value_with<T>( &mut self, fulfil: impl FnOnce() -> T ) -> &mut Demand<'a>where T: 'static,

🔬This is a nightly-only experimental API. (provide_any #96024)

Provide a value or other type with only static lifetimes computed using a closure.

Examples

Provides a String by cloning.

#![feature(provide_any)]

use std::any::{Provider, Demand};

impl Provider for SomeConcreteType {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        demand.provide_value_with::<String>(|| self.field.clone());
    }
}
Run
source

pub fn provide_ref<T>(&mut self, value: &'a T) -> &mut Demand<'a>where T: 'static + ?Sized,

🔬This is a nightly-only experimental API. (provide_any #96024)

Provide a reference. The referee type must be bounded by 'static, but may be unsized.

Examples

Provides a reference to a field as a &str.

#![feature(provide_any)]

use std::any::{Provider, Demand};

impl Provider for SomeConcreteType {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        demand.provide_ref::<str>(&self.field);
    }
}
Run
source

pub fn provide_ref_with<T>( &mut self, fulfil: impl FnOnce() -> &'a T ) -> &mut Demand<'a>where T: 'static + ?Sized,

🔬This is a nightly-only experimental API. (provide_any #96024)

Provide a reference computed using a closure. The referee type must be bounded by 'static, but may be unsized.

Examples

Provides a reference to a field as a &str.

#![feature(provide_any)]

use std::any::{Provider, Demand};

impl Provider for SomeConcreteType {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        demand.provide_ref_with::<str>(|| {
            if today_is_a_weekday() {
                &self.business
            } else {
                &self.party
            }
        });
    }
}
Run
source

pub fn would_be_satisfied_by_value_of<T>(&self) -> boolwhere T: 'static,

🔬This is a nightly-only experimental API. (provide_any #96024)

Check if the Demand would be satisfied if provided with a value of the specified type. If the type does not match or has already been provided, returns false.

Examples

Check if an u8 still needs to be provided and then provides it.

#![feature(provide_any)]

use std::any::{Provider, Demand};

struct Parent(Option<u8>);

impl Provider for Parent {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        if let Some(v) = self.0 {
            demand.provide_value::<u8>(v);
        }
    }
}

struct Child {
    parent: Parent,
}

impl Child {
    // Pretend that this takes a lot of resources to evaluate.
    fn an_expensive_computation(&self) -> Option<u8> {
        Some(99)
    }
}

impl Provider for Child {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        // In general, we don't know if this call will provide
        // an `u8` value or not...
        self.parent.provide(demand);

        // ...so we check to see if the `u8` is needed before
        // we run our expensive computation.
        if demand.would_be_satisfied_by_value_of::<u8>() {
            if let Some(v) = self.an_expensive_computation() {
                demand.provide_value::<u8>(v);
            }
        }

        // The demand will be satisfied now, regardless of if
        // the parent provided the value or we did.
        assert!(!demand.would_be_satisfied_by_value_of::<u8>());
    }
}

let parent = Parent(Some(42));
let child = Child { parent };
assert_eq!(Some(42), std::any::request_value::<u8>(&child));

let parent = Parent(None);
let child = Child { parent };
assert_eq!(Some(99), std::any::request_value::<u8>(&child));
Run
source

pub fn would_be_satisfied_by_ref_of<T>(&self) -> boolwhere T: 'static + ?Sized,

🔬This is a nightly-only experimental API. (provide_any #96024)

Check if the Demand would be satisfied if provided with a reference to a value of the specified type. If the type does not match or has already been provided, returns false.

Examples

Check if a &str still needs to be provided and then provides it.

#![feature(provide_any)]

use std::any::{Provider, Demand};

struct Parent(Option<String>);

impl Provider for Parent {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        if let Some(v) = &self.0 {
            demand.provide_ref::<str>(v);
        }
    }
}

struct Child {
    parent: Parent,
    name: String,
}

impl Child {
    // Pretend that this takes a lot of resources to evaluate.
    fn an_expensive_computation(&self) -> Option<&str> {
        Some(&self.name)
    }
}

impl Provider for Child {
    fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
        // In general, we don't know if this call will provide
        // a `str` reference or not...
        self.parent.provide(demand);

        // ...so we check to see if the `&str` is needed before
        // we run our expensive computation.
        if demand.would_be_satisfied_by_ref_of::<str>() {
            if let Some(v) = self.an_expensive_computation() {
                demand.provide_ref::<str>(v);
            }
        }

        // The demand will be satisfied now, regardless of if
        // the parent provided the reference or we did.
        assert!(!demand.would_be_satisfied_by_ref_of::<str>());
    }
}

let parent = Parent(Some("parent".into()));
let child = Child { parent, name: "child".into() };
assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));

let parent = Parent(None);
let child = Child { parent, name: "child".into() };
assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
Run

Trait Implementations§

source§

impl<'a> Debug for Demand<'a>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

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

§

impl<'a> !Send for Demand<'a>

§

impl<'a> !Sized for Demand<'a>

§

impl<'a> !Sync for Demand<'a>

§

impl<'a> !Unpin for Demand<'a>

§

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

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more