Skip to main content

Functional

Struct Functional 

Source
pub struct Functional<Str> {
    pub namespace: Str,
    pub can_handle: fn(&ContextCanHandle<'_, '_, '_>) -> bool,
    pub handle: fn(&mut ContextHandle<'_, '_, '_, '_, '_>),
}
Expand description

A powerful kind allowing the use a Rust function to handle all selectors in the form <namespace>-....

This plugin kind is (of course) not serializable.

The can_handle field function takes a ContextCanHandle structure and returns whether the plugin is capable of handling the utility class given in the context.

The handle field function takes a ContextHandle structure containing the modifier, the current configuration and a buffer containing the whole CSS currently generated. You can use the Buffer structure (especially the Buffer::line and Buffer::lines functions) to push CSS declarations to it, they will be automatically indented.

generate_wrapper (and the more powerful generate_at_rules and generate_class) should be called to generate the CSS rule wrapping.

§Example

use encre_css::{Config, generate};
use encre_css::prelude::build_plugin::*;
use std::collections::HashMap;

/// Reads the `emoji` extra field of the configuration to find the replacement emoji.
fn extract_emoji_value<'a>(config: &'a Config, value: &str) -> Option<&'a str> {
    config.extra.get("emoji")
        .and_then(|r| r.as_table())
        .and_then(|r| r.get(value))
        .and_then(|r| r.as_str())
}

const PLUGIN: StaticPlugin = Plugin::Functional(Functional {
    namespace: "emoji",
    can_handle: |context| matches!(context.modifier, Modifier::Builtin {
        value,
        ..
    } if extract_emoji_value(context.config, value).is_some()),
    handle: |context| {
        // Only accept static modifiers, and dynamically fetch them from the
        // `emoji` extra field of the configuration
        if let Modifier::Builtin { value, .. } = context.modifier
        && let Some(value) = extract_emoji_value(&context.config, value) {
            generate_wrapper(context, |context| {
                context.buffer.line(format_args!("content: \"{value}\";"));
            });
        }
    },
});

let mut config = Config::default();
config.extra.add(
    "emoji",
    HashMap::from_iter([("tada", "\u{1f389}"), ("rocket", "\u{1f680}")]),
);
config.register_plugin(&PLUGIN);

let generated = generate(["emoji-tada", "emoji-rocket"], &config);

assert!(generated.ends_with(".emoji-rocket {
  content: \"\u{1f680}\";
}

.emoji-tada {
  content: \"\u{1f389}\";
}"));

Fields§

§namespace: Str

The namespace (i.e common prefix) that all classes need to start with in order to be matched by this plugin.

§can_handle: fn(&ContextCanHandle<'_, '_, '_>) -> bool

A function returning whether a specific class (passed inside the context) is matched by this plugin.

§handle: fn(&mut ContextHandle<'_, '_, '_, '_, '_>)

A function called to generate the CSS of a matched class.

It should use generate_wrapper (and the more powerful generate_at_rules and generate_class) to generate the CSS rule wrapping.

Various notes:

  • The CSS written should end with a newline
  • Arbitrary values are already normalized (e.g. underscores are replaced by spaces)
  • This function is guaranteed to be called only once per selector

Implementations§

Source§

impl Functional<&'static str>

Source

pub const fn default() -> Self

Make a default Functional plugin kind.

All required fields are initialized with empty values and optional fields are initialized with None.

You should at least set Functional::namespace, Functional::can_handle and Functional::handle after calling this function.

This function is intended to be used as an automatic filler for default values using the struct update syntax.

The difference with Functional::default_dynamic is that this function can only be used to build a plugin using static structures like &[]s, &'static strs.

§Example
use encre_css::prelude::build_plugin::*;

const PLUGIN: StaticPlugin = Plugin::Functional(Functional {
    namespace: "emoji",
    can_handle: |context| matches!(context.modifier, Modifier::Builtin { value: "tada", .. }),
    handle: |context| {
        generate_wrapper(context, |context| {
            context.buffer.line(format_args!("content: \"\u{1f389}\";"));
        });
    },
    ..Functional::default()
});
Source§

impl Functional<String>

Source

pub fn default_dynamic() -> Self

Make a default Functional plugin kind.

All required fields are initialized with empty values and optional fields are initialized with None.

You should at least set Functional::namespace, Functional::can_handle and Functional::handle after calling this function.

This function is intended to be used as an automatic filler for default values using the struct update syntax.

The difference with Functional::default is that this function can only be used to build a plugin using heap-allocated structures like Strings, Vecs.

§Example
use encre_css::prelude::build_plugin::*;

fn main() {
    // Note: the DynamicPlugin type hint is required to help the compiler
    // find the concrete types of type parameters
    let _plugin: DynamicPlugin = Plugin::Functional(Functional {
        namespace: "emoji".to_string(),
        can_handle: |context| matches!(context.modifier, Modifier::Builtin { value: "tada", .. }),
        handle: |context| {
            generate_wrapper(context, |context| {
                context.buffer.line(format_args!("content: \"\u{1f389}\";"));
            });
        },
        ..Functional::default_dynamic()
    });
}

This example is equivalent to the one of Functional::default.

Trait Implementations§

Source§

impl<Str: Clone> Clone for Functional<Str>

Source§

fn clone(&self) -> Functional<Str>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl<Str: Debug> Debug for Functional<Str>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Str> Freeze for Functional<Str>
where Str: Freeze,

§

impl<Str> RefUnwindSafe for Functional<Str>
where Str: RefUnwindSafe,

§

impl<Str> Send for Functional<Str>
where Str: Send,

§

impl<Str> Sync for Functional<Str>
where Str: Sync,

§

impl<Str> Unpin for Functional<Str>
where Str: Unpin,

§

impl<Str> UnsafeUnpin for Functional<Str>
where Str: UnsafeUnpin,

§

impl<Str> UnwindSafe for Functional<Str>
where Str: 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§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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,

Source§

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

Source§

type Error = !

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

Source§

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.