some refractoring
This commit is contained in:
+158
-135
@@ -6,16 +6,27 @@ use std::{collections::HashMap, fmt::Debug};
|
||||
|
||||
use dyn_clone::{clone_trait_object, DynClone};
|
||||
|
||||
use crate::RenderResult;
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Type aliases
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub type Css = HashMap<StyleName, Style>;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Traits
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub trait StyleCore: Debug + Send + Sync + DynClone {
|
||||
fn ansi(&self) -> String;
|
||||
fn ansi_bg(&self) -> String;
|
||||
fn is_null(&self) -> bool;
|
||||
}
|
||||
|
||||
clone_trait_object!(StyleCore);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Enums
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Font {
|
||||
None,
|
||||
@@ -27,32 +38,6 @@ pub enum Font {
|
||||
Mul(Vec<Font>),
|
||||
}
|
||||
|
||||
impl StyleCore for Font {
|
||||
fn ansi(&self) -> String {
|
||||
String::from(match self {
|
||||
Font::None => "",
|
||||
Font::Bold => "\x1b[1m",
|
||||
Font::Underline => "\x1b[4m",
|
||||
Font::Italic => "\x1b[3m",
|
||||
Font::Reverse => "\x1b[7m",
|
||||
Font::Strike => "\x1b[9m",
|
||||
Font::Mul(v) => {
|
||||
let mut s = String::new();
|
||||
for n in v {
|
||||
s += n.ansi().as_str();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
})
|
||||
}
|
||||
fn ansi_bg(&self) -> String {
|
||||
self.ansi()
|
||||
}
|
||||
fn is_null(&self) -> bool {
|
||||
*self == Self::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Color {
|
||||
NoColor,
|
||||
@@ -68,6 +53,128 @@ pub enum Color {
|
||||
White,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Number {
|
||||
Px(usize),
|
||||
Pe(usize),
|
||||
Center,
|
||||
Auto,
|
||||
Default,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
|
||||
pub enum StyleName {
|
||||
Class(String),
|
||||
Id(String),
|
||||
Component(String),
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Structs
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StyleElement {
|
||||
pub color: Color,
|
||||
pub background: Color,
|
||||
pub font: Font,
|
||||
pub x: Number,
|
||||
pub y: Number,
|
||||
pub width: Number,
|
||||
pub height: Number,
|
||||
pub other: HashMap<String, Box<dyn StyleCore>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Style(
|
||||
pub StyleElement,
|
||||
pub HashMap<String, StyleElement>,
|
||||
pub String,
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementations
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Default for Style {
|
||||
fn default() -> Self {
|
||||
Style(StyleElement::default(), HashMap::new(), String::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub fn get(&self, hover: bool) -> StyleElement {
|
||||
if let Some(style_element) = self.1.get(&self.2) {
|
||||
self.0.clone().prioritize(style_element)
|
||||
} else if hover {
|
||||
if let Some(style_element) = self.1.get("hover") {
|
||||
self.0.clone().prioritize(style_element)
|
||||
} else {
|
||||
self.0.clone()
|
||||
}
|
||||
} else {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_state(&mut self, state: &str) {
|
||||
self.2 = state.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleElement {
|
||||
pub fn write(&self, s: &str) -> String {
|
||||
format!(
|
||||
"{}{}{}{s}\x1b[0m",
|
||||
self.color.ansi(),
|
||||
self.background.ansi_bg(),
|
||||
self.font.ansi()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for StyleElement {
|
||||
fn default() -> Self {
|
||||
StyleElement {
|
||||
color: Color::NoColor,
|
||||
background: Color::NoColor,
|
||||
font: Font::None,
|
||||
x: Number::Default,
|
||||
y: Number::Default,
|
||||
width: Number::Default,
|
||||
height: Number::Default,
|
||||
other: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleElement {
|
||||
pub fn prioritize(mut self, other: &Self) -> StyleElement {
|
||||
if !other.color.is_null() {
|
||||
self.color = other.color.clone();
|
||||
}
|
||||
if !other.background.is_null() {
|
||||
self.background = other.background.clone();
|
||||
}
|
||||
if !other.font.is_null() {
|
||||
self.font = other.font.clone();
|
||||
}
|
||||
if other.x != Number::Default {
|
||||
self.x = other.x.clone();
|
||||
}
|
||||
if other.y != Number::Default {
|
||||
self.y = other.y.clone();
|
||||
}
|
||||
if other.width != Number::Default {
|
||||
self.width = other.width.clone();
|
||||
}
|
||||
if other.height != Number::Default {
|
||||
self.height = other.height.clone();
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleCore for Color {
|
||||
fn ansi(&self) -> String {
|
||||
String::from(match self {
|
||||
@@ -153,112 +260,28 @@ fn hex_to_rgb(hex: &str) -> (u8, u8, u8) {
|
||||
(r, g, b)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Number {
|
||||
Px(usize),
|
||||
Pe(usize),
|
||||
Center,
|
||||
Auto,
|
||||
Default,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
|
||||
pub enum StyleName {
|
||||
Class(String),
|
||||
Id(String),
|
||||
Component(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StyleElement {
|
||||
pub color: Color,
|
||||
pub background: Color,
|
||||
pub font: Font,
|
||||
pub x: Number,
|
||||
pub y: Number,
|
||||
pub width: Number,
|
||||
pub height: Number,
|
||||
pub other: HashMap<String, Box<dyn StyleCore>>,
|
||||
}
|
||||
|
||||
impl Default for StyleElement {
|
||||
fn default() -> Self {
|
||||
StyleElement {
|
||||
color: Color::NoColor,
|
||||
background: Color::NoColor,
|
||||
font: Font::None,
|
||||
x: Number::Default,
|
||||
y: Number::Default,
|
||||
width: Number::Default,
|
||||
height: Number::Default,
|
||||
other: HashMap::new(),
|
||||
}
|
||||
impl StyleCore for Font {
|
||||
fn ansi(&self) -> String {
|
||||
String::from(match self {
|
||||
Font::None => "",
|
||||
Font::Bold => "\x1b[1m",
|
||||
Font::Underline => "\x1b[4m",
|
||||
Font::Italic => "\x1b[3m",
|
||||
Font::Reverse => "\x1b[7m",
|
||||
Font::Strike => "\x1b[9m",
|
||||
Font::Mul(v) => {
|
||||
let mut s = String::new();
|
||||
for n in v {
|
||||
s += n.ansi().as_str();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
})
|
||||
}
|
||||
fn ansi_bg(&self) -> String {
|
||||
self.ansi()
|
||||
}
|
||||
fn is_null(&self) -> bool {
|
||||
*self == Self::None
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleElement {
|
||||
pub fn prioritize(mut self, other: &Self) -> StyleElement {
|
||||
if !other.color.is_null() {
|
||||
self.color = other.color.clone();
|
||||
}
|
||||
if !other.background.is_null() {
|
||||
self.background = other.background.clone();
|
||||
}
|
||||
if !other.font.is_null() {
|
||||
self.font = other.font.clone();
|
||||
}
|
||||
if other.x != Number::Default {
|
||||
self.x = other.x.clone();
|
||||
}
|
||||
if other.y != Number::Default {
|
||||
self.y = other.y.clone();
|
||||
}
|
||||
if other.width != Number::Default {
|
||||
self.width = other.width.clone();
|
||||
}
|
||||
if other.height != Number::Default {
|
||||
self.height = other.height.clone();
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Style(pub StyleElement, pub HashMap<String, StyleElement>);
|
||||
|
||||
impl Default for Style {
|
||||
fn default() -> Self {
|
||||
Style(StyleElement::default(), HashMap::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub fn write(&self, state: &str, s: &str) -> String {
|
||||
if let Some(style_element) = self.1.get(state) {
|
||||
style_element.write(s)
|
||||
} else {
|
||||
return self.0.write(s);
|
||||
}
|
||||
}
|
||||
pub fn result(&self, state: &str, s: String) -> RenderResult {
|
||||
if let Some(style_element) = self.1.get(state) {
|
||||
let style_element = self.0.clone().prioritize(&style_element.clone());
|
||||
RenderResult(s, (style_element.x.clone(), style_element.y.clone()))
|
||||
} else {
|
||||
RenderResult(s, (self.0.x.clone(), self.0.y.clone()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleElement {
|
||||
pub fn write(&self, s: &str) -> String {
|
||||
format!(
|
||||
"{}{}{}{s}\x1b[0m",
|
||||
self.color.ansi(),
|
||||
self.background.ansi_bg(),
|
||||
self.font.ansi()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub type Css = HashMap<StyleName, Style>;
|
||||
|
||||
Reference in New Issue
Block a user