[][src]Trait mail_core::context::Context

pub trait Context: Debug + Clone + Send + Sync + 'static {
    fn load_resource(
        &self,
        source: &Source
    ) -> SendBoxFuture<MaybeEncData, ResourceLoadingError>;
fn generate_message_id(&self) -> MessageId;
fn generate_content_id(&self) -> ContentId;
fn offload<F>(&self, fut: F) -> SendBoxFuture<F::Item, F::Error>
    where
        F: Future + Send + 'static,
        F::Item: Send + 'static,
        F::Error: Send + 'static
; fn load_transfer_encoded_resource(
        &self,
        resource: &Resource
    ) -> SendBoxFuture<EncData, ResourceLoadingError> { ... }
fn offload_fn<FN, I>(&self, func: FN) -> SendBoxFuture<I::Item, I::Error>
    where
        FN: FnOnce() -> I + Send + 'static,
        I: IntoFuture + 'static,
        I::Future: Send + 'static,
        I::Item: Send + 'static,
        I::Error: Send + 'static
, { ... } }

This library needs a context for creating/encoding mails.

The context is not meant to be a think you create once per mail but something you create once one startup and then re-user wherever it is needed in your application.

A context impl. provides following functionality to this library:

  1. Load a Resource based on a Source instance. I.e. an IRI plus some optional meta information.
  2. Generate an unique message id. This should be an world unique id to comply with the standard(s).
  3. Generate an unique content id. This should be an world unique id to comply with the standard(s).
  4. A way to "offload" work to some other "place" e.g. by scheduling it in an thread pool.

The CompositeContext provides a impl. for this trait which delegates the different tasks to the components it's composed of. This allow to reuse e.g. the message if generation and offloading but use a custom resource loading. Generally it's recommended to use the CompositeContext.

There is also an default implementation (using the CompositeContext in the default_impl module).

Clone / Send / Sync / 'static ?

Context are meant to be easily shareable, cloning them should be cheap, as such if a implementor contains state it might make sense for an implementor to have a outer+inner type where the inner type is wrapped into a Arc e.g. struct SomeCtx { inner: Arc<InnerSomeCtx> }.

Required methods

fn load_resource(
    &self,
    source: &Source
) -> SendBoxFuture<MaybeEncData, ResourceLoadingError>

Loads and transfer encodes a Data instance.

This is called when a Mail instance is converted into a encodable mail an a Resource::Data instance is found.

This can potentially use the IRI to implement a simple caching scheme potentially directly caching the transfer encoded instance skipping the loading + encoding step for common resources like e.g. a logo.

If the context implementation only caches enc data instances but not data instances it might return MaybeEncData::EncData. If it newly load the resource it should return a MaybeEncData::Data variant.

Async Considerations

This function should not block and schedule the encoding in some other place e.g. by using the contexts offload functionality.

fn generate_message_id(&self) -> MessageId

generate a unique content id

As message id's are used to reference messages they should be world unique this can be guaranteed through two aspects:

  1. using a domain you own/control on the right hand side of the @ will make sure no id's from other persons/companies/... will collide with your ids

  2. using some internal mechanism for the left hand side, like including the time and an internal counter, not that you have to make sure this stays unique even if you run multiple instances or restart the current running instance.

fn generate_content_id(&self) -> ContentId

generate a unique content id

Rfc 2045 states that content id's have to be world unique, while this really should be the case if it's used in combination with an multipart/external or similar body for it's other usage as reference for embeddings it being mail unique tends to be enough.

As content id and message id are treated mostly the same wrt. the constraints applying when generating them this can be implemented in terms of calling generate_message_id.

fn offload<F>(&self, fut: F) -> SendBoxFuture<F::Item, F::Error> where
    F: Future + Send + 'static,
    F::Item: Send + 'static,
    F::Error: Send + 'static, 

offloads the execution of the future fut to somewhere else e.g. a cpu pool

Loading content...

Provided methods

fn load_transfer_encoded_resource(
    &self,
    resource: &Resource
) -> SendBoxFuture<EncData, ResourceLoadingError>

Loads and Transfer encodes a Resource instance.

This is called when a Mail instance is converted into a encodable mail.

The default impl. of this function just:

  1. calls load_resource and chains a "offloaded" transfer encoding if a Resource::Source is found.
  2. transfer encodes the data "offloaded" if Resource::Data is found
  3. just returns the encoded data if Resource::EncData is found

A more advances implementation could for example integrate a LRU cache.

The default impl is available as the default_impl_for_load_transfer_encoded_resource function.

Async Considerations

This function should not block and schedule the encoding in some other place e.g. by using the contexts offload functionality.

fn offload_fn<FN, I>(&self, func: FN) -> SendBoxFuture<I::Item, I::Error> where
    FN: FnOnce() -> I + Send + 'static,
    I: IntoFuture + 'static,
    I::Future: Send + 'static,
    I::Item: Send + 'static,
    I::Error: Send + 'static, 

offloads the execution of the function func to somewhere else e.g. a cpu pool

Loading content...

Implementors

impl<R, O, M> Context for CompositeContext<R, O, M> where
    R: ResourceLoaderComponent,
    O: OffloaderComponent,
    M: MailIdGenComponent
[src]

fn offload_fn<FN, I>(&self, func: FN) -> SendBoxFuture<I::Item, I::Error> where
    FN: FnOnce() -> I + Send + 'static,
    I: IntoFuture + 'static,
    I::Future: Send + 'static,
    I::Item: Send + 'static,
    I::Error: Send + 'static, 
[src]

Loading content...