//! # grass //! An implementation of the sass specification in pure rust. //! //! All functionality is currently exposed through [`StyleSheet`]. //! //! Spec progress as of 2020-03-20: //! //! | Passing | Failing | Total | //! |---------|---------|-------| //! | 1394 | 3699 | 5093 | //! //! ## Use as library //! ``` //! use std::io::{BufWriter, stdout}; //! use grass::{SassResult, StyleSheet}; //! //! fn main() -> SassResult<()> { //! let mut buf = BufWriter::new(stdout()); //! StyleSheet::from_path("input.scss")?.print_as_css(&mut buf) //! } //! ``` //! //! ## Use as binary //! ```bash //! cargo install grass //! grass input.scss //! ``` #![warn( clippy::all, clippy::restriction, clippy::pedantic, clippy::nursery, clippy::cargo )] #![deny(missing_debug_implementations)] #![allow( // explicit return makes some things look ugly clippy::implicit_return, // Self { .. } is less explicit than Foo { .. } clippy::use_self, // this is way too pedantic -- some things don't need docs! clippy::missing_docs_in_private_items, // unreachable!() has many valid use cases clippy::unreachable, // _ => {} has many valid use cases clippy::wildcard_enum_match_arm, // .expect() has many valid use cases, like when we know a value is `Some(..)` clippy::option_expect_used, // this is too pedantic -- we are allowed to add numbers! clippy::integer_arithmetic, // this is too pedantic for now -- the library is changing too quickly for // good docs to be written clippy::missing_errors_doc, // this incorrectly results in errors for types that derive `Debug` // https://github.com/rust-lang/rust-clippy/issues/4980 clippy::let_underscore_must_use, // this is too pedantic -- it results in some names being less explicit // than they should clippy::module_name_repetitions, clippy::option_unwrap_used, // this is too pedantic -- it is sometimes useful to break up `impl`s clippy::multiple_inherent_impl, // temporarily allowed while under heavy development. // eventually these allows should be refactored away // to no longer be necessary clippy::as_conversions, clippy::todo, clippy::too_many_lines, clippy::panic, clippy::result_unwrap_used, clippy::result_expect_used, clippy::cast_possible_truncation, clippy::single_match_else, clippy::indexing_slicing, clippy::match_same_arms, clippy::or_fun_call, )] #![cfg_attr(feature = "nightly", feature(track_caller))] use std::fmt::{self, Display}; use std::fs; use std::io::Write; use std::iter::{Iterator, Peekable}; use std::path::Path; use crate::atrule::{AtRule, AtRuleKind}; use crate::common::{Pos, Symbol, Whitespace}; use crate::css::Css; use crate::error::SassError; pub use crate::error::SassResult; use crate::format::PrettyPrinter; use crate::function::Function; use crate::imports::import; use crate::lexer::Lexer; use crate::mixin::{eat_include, Mixin}; use crate::scope::{insert_global_var, Scope, GLOBAL_SCOPE}; use crate::selector::Selector; use crate::style::Style; pub(crate) use crate::token::{Token, TokenKind}; use crate::utils::{devour_whitespace, eat_variable_value, VariableDecl}; use crate::value::Value; mod args; mod atrule; mod builtin; mod color; mod common; mod css; mod error; mod format; mod function; mod imports; mod lexer; mod mixin; mod scope; mod selector; mod style; mod token; mod unit; mod utils; mod value; pub(crate) fn error>(msg: E) -> ! { eprintln!("Error: {}", msg.into()); std::process::exit(1); } /// Represents a parsed SASS stylesheet with nesting #[derive(Debug, Clone)] pub struct StyleSheet(Vec); #[derive(Clone, Debug)] pub(crate) enum Stmt { /// A [`Style`](/grass/style/struct.Style) Style(Box