use std::borrow::Cow;
use std::rc::Rc;
use crate::manager::{StyleContent, StyleId, StyleKey, StyleManager};
use crate::{Result, StyleSource};
#[derive(Debug, Clone)]
pub struct Style {
inner: Rc<StyleContent>,
}
impl Style {
fn create_impl(
class_prefix: Cow<'static, str>,
css: StyleSource,
manager: StyleManager,
) -> Result<Self> {
let css = css.into_sheet();
let key = StyleKey {
is_global: false,
prefix: class_prefix,
ast: css,
};
let inner = manager.get_or_register_style(key)?;
let new_style = Self { inner };
Ok(new_style)
}
pub fn new<Css>(css: Css) -> Result<Self>
where
Css: TryInto<StyleSource>,
crate::Error: From<Css::Error>,
{
Self::create(StyleManager::default().prefix(), css)
}
pub fn create<N, Css>(class_prefix: N, css: Css) -> Result<Self>
where
N: Into<Cow<'static, str>>,
Css: TryInto<StyleSource>,
crate::Error: From<Css::Error>,
{
Self::create_with_manager(class_prefix, css, StyleManager::default())
}
pub fn new_with_manager<Css, M>(css: Css, manager: M) -> Result<Self>
where
Css: TryInto<StyleSource>,
crate::Error: From<Css::Error>,
M: Into<StyleManager>,
{
let mgr = manager.into();
Self::create_with_manager(mgr.prefix(), css, mgr.clone())
}
pub fn create_with_manager<N, Css, M>(class_prefix: N, css: Css, manager: M) -> Result<Self>
where
N: Into<Cow<'static, str>>,
Css: TryInto<StyleSource>,
crate::Error: From<Css::Error>,
M: Into<StyleManager>,
{
Self::create_impl(class_prefix.into(), css.try_into()?, manager.into())
}
pub fn get_class_name(&self) -> &str {
self.inner.id()
}
pub fn get_style_str(&self) -> &str {
self.inner.get_style_str()
}
#[cfg(test)]
pub(crate) fn key(&self) -> &Rc<StyleKey> {
self.inner.key()
}
pub fn unregister(&self) {
self.inner.unregister();
}
pub fn id(&self) -> &StyleId {
self.inner.id()
}
}
#[cfg(test)]
#[cfg(feature = "parser")]
mod tests {
use super::*;
#[test]
fn test_simple() {
Style::new("background-color: black;").expect("Failed to create Style.");
}
#[test]
fn test_complex() {
let style = Style::new(
r#"
background-color: black;
.with-class {
color: red;
}
@media screen and (max-width: 600px) {
color: yellow;
}
@supports (display: grid) {
display: grid;
}
header, footer {
border: 1px solid black;
@supports (max-width: 500px) {
@media screen and (max-width: 500px) {
display: flex;
}
}
}
"#,
)
.expect("Failed to create Style.");
assert_eq!(
style.get_style_str(),
format!(
r#".{style_name} {{
background-color: black;
}}
.{style_name} .with-class {{
color: red;
}}
@media screen and (max-width: 600px) {{
.{style_name} {{
color: yellow;
}}
}}
@supports (display: grid) {{
.{style_name} {{
display: grid;
}}
}}
.{style_name} header, .{style_name} footer {{
border: 1px solid black;
}}
@supports (max-width: 500px) {{
@media screen and (max-width: 500px) {{
.{style_name} header, .{style_name} footer {{
display: flex;
}}
}}
}}
"#,
style_name = style.get_class_name()
)
)
}
}