inline-css 0.0.3

Embed CSS directly in your Rust code
Documentation
// Copyright (C) 2023 Benjamin Stürz
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//! Embed CSS directly into your Rust code.
//!
//! # Example
//! ``` rust
//! use inline_css::*;
//!
//! let x = 42;
//!
//! let css = css! {
//!     h1 {
//!         color: red;
//!         background-color: #0x00ffff; // not #00ffff
//!         padding: 10px;
//!         margin-left: 10m; // not 10em
//!         margin-right: -4%;
//!     }
//! };
//!
//! println!("{css}");
//! ```
//!
//! # How to use
//! Use the [`css! {..}`](crate::css) macro to embed CSS directly into your Rust code.
//! During the compile-time of your Rust program, the content inside of your `css!` invocations
//! will be checked and converted to an instance of [`CSS`](crate::CSS).
//! This makes sure that all invocations of the `css!` macro are guaranteed to be valid CSS at runtime.
//!
//! ## Integration with inline-xml
//! inline-css implements [`ToXml`](https://docs.rs/inline-xml/latest/inline_xml/trait.ToXml.html) for [`CSS`](crate::CSS) for integration with [`inline-xml`](https://docs.rs/inline-xml/latest/inline_xml).
//!
//! ### Example
//! ``` rust,ignore
//! extern crate inline_xml;
//! use inline_xml::xml;
//! use inline_css::css;
//!
//! let css = css! {
//!     h1 {
//!         color: red;
//!     }
//! };
//!
//! let html = xml! {
//!     <html>
//!         <head>
//!             <style>{css}</style>
//!         </head>
//!         <body>
//!             <h1>Hello World</h1>
//!         </body>
//!     </html>
//! };
//! ```
//!
//!
//! ## Variants
//! There are 3 macros:
//! ### [`css!`](crate::css)
//! Parse an entire snippet of [CSS](crate::CSS).
//!
//! ``` rust
//! use inline_css::*;
//!
//! let rule: CSS = css! {
//!     h1 {
//!         color: red;
//!     }
//!
//!     .button {
//!         color: blue;
//!     }
//!
//!     #text {
//!         color: green;
//!     }
//! };
//! ```
//!
//! ### [`css_rule!`](crate::css_rule)
//! Parse a single CSS [Rule](crate::Rule).
//!
//! ``` rust
//! use inline_css::*;
//!
//! let rule: Rule = css_rule! {
//!     h1 {
//!         color: red;
//!     }
//! };
//! ```
//! ### [`css_value!`](crate::css_value)
//! Parse a CSS [Value](crate::Value).
//!
//! ``` rust
//! use inline_css::*;
//!
//! let value: Value = css_value! { 10px };
//! ```
//!
//! # Dynamic Data
//! You can include dynamically-generated data into the `css!` macro invocation.
//!
//! Only types implementing `Into<Value>` are supported.
//!
//! ## Example
//! ``` rust
//! use inline_css::*;
//!
//! let x = 42;
//! let css = css! {
//!     h1 {
//!         attr: {x + 1};
//!     }
//! };
//! ```

mod fmt;
#[cfg(feature = "inline-xml")]
mod xml;
#[cfg(test)]
mod tests;
mod impls;

/// Parse an entire snippet of [CSS](crate::CSS).
///
/// See the [crate-level documentation](crate#css).
pub use inline_css_macros::css;

/// Parse a CSS [Rule](crate::Rule).
///
/// See the [crate-level documentation](crate#css_rule).
pub use inline_css_macros::css_rule;

/// Parse a CSS [Value](crate::Value).
///
/// See the [crate-level documentation](crate#css_value).
pub use inline_css_macros::css_value;

/// CSS holds an entire snippet of CSS.
///
/// See the [crate-level documentation](crate#css).
#[derive(Debug, Clone, PartialEq)]
pub struct CSS(pub Vec<Rule>);

/// A single CSS rule.
///
/// See the [crate-level documentation](crate#css_rule).
#[derive(Debug, Clone, PartialEq)]
pub struct Rule {
    pub selector: Selector,
    pub declarations: Vec<Declaration>,
}

/// A CSS selector.
#[derive(Debug, Clone, PartialEq)]
pub enum Selector {
    Any,
    Simple {
        ty: Option<String>,
        class: Option<String>,
        id: Option<String>,
    },
    Colon {
        name: String,
        arg: Option<Value>,
    },
    Sub {
        left: Box<Selector>,
        right: Box<Selector>,
    },
    Gt {
        left: Box<Selector>,
        right: Box<Selector>,
    },
    Plus {
        left: Box<Selector>,
        right: Box<Selector>,
    },
    Tilde {
        left: Box<Selector>,
        right: Box<Selector>,
    },
    Comma {
        left: Box<Selector>,
        right: Box<Selector>,
    },
}

/// A CSS declaration.
#[derive(Debug, Clone, PartialEq)]
pub struct Declaration {
    pub name: String,
    pub value: Vec<Value>,
}

/// A CSS value.
///
/// See the [crate-level documentation](crate#css_value).
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
    ColorCode(u32),
    Ident(String),
    Int(i32, String),
    Float(f32, String),
    Function {
        name: String,
        args: Vec<Value>,
    }
}