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: StrThe namespace (i.e common prefix) that all classes need to start with in order to be matched by this plugin.
can_handle: fn(&ContextCanHandle<'_, '_, '_>) -> boolA 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>
impl Functional<&'static str>
Sourcepub const fn default() -> Self
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>
impl Functional<String>
Sourcepub fn default_dynamic() -> Self
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>
impl<Str: Clone> Clone for Functional<Str>
Source§fn clone(&self) -> Functional<Str>
fn clone(&self) -> Functional<Str>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more