1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
/// Stylesheet Builder
use utils::{generic_erase, StylePropertyField};
use erased_serde::{Deserializer, deserialize};
use std::collections::HashMap;
use std::boxed::Box;

use traits::{
    TParseStylesheetMiddleware,
    TParseStyleMiddleware,
};

use types::{
    ParseStylesheetMiddleware,
    StylesheetFieldInfo,
    FieldParseType,
    SourceFormat,
    Stylesheet,
    ParseError,
    Case,
};

pub struct StylesheetBuilder {
    style_custom_middlewares: HashMap<String, Box<TParseStyleMiddleware>>,
    custom_middlewares: HashMap<String, Box<TParseStylesheetMiddleware>>,
    default_middleware: Box<TParseStylesheetMiddleware>,

    source_type: SourceFormat,
    case: Case,
}

#[derive(Clone, Debug, Copy)]
pub struct StylesheetOptions {
    pub source_type: SourceFormat,
    pub case: Case,
}

impl Default for StylesheetBuilder {
    fn default() -> StylesheetBuilder {
        StylesheetBuilder {
            default_middleware: Box::new(ParseStylesheetMiddleware {}),
            style_custom_middlewares: HashMap::default(),
            custom_middlewares: HashMap::default(),
            source_type: SourceFormat::Json,
            case: Case::Ignore,
        }
    }
}

impl StylesheetBuilder {
    pub fn middleware(mut self, middleware: Box<TParseStylesheetMiddleware>) -> Self {
        self.custom_middlewares.insert(middleware.name(), middleware);
        self
    }

    pub fn style_middleware(mut self, middleware: Box<TParseStyleMiddleware>) -> Self {
        self.style_custom_middlewares.insert(middleware.name(), middleware);
        self
    }

    pub fn case(mut self, case: Case) -> Self {
        self.case = case;
        self
    }

    pub fn source_type(mut self, source_type: SourceFormat) -> Self {
        self.source_type = source_type;
        self
    }

    pub fn parse_from_str(&mut self, source: &str) -> Result<Stylesheet, ParseError> {
        let erased = generic_erase(source, self.source_type)?;
        let mut stylesheet = Stylesheet::default();
        
        let options = StylesheetOptions {
            source_type: self.source_type,
            case: self.case,
        };

        for (key, value) in erased {
            let key = StylesheetFieldInfo::new(key.as_str());
            
            match key.key_type {
                FieldParseType::Variable => {
                    // @todo: handle this
                },

                FieldParseType::Custom => {
                    self.custom_middlewares.get_mut(&key.name)
                        .ok_or(ParseError::MissingMiddleware { name: key.name.clone() })
                        .and_then(|middleware| middleware.process_value(key, value, &mut stylesheet, options))?;
                },

                FieldParseType::Default => {
                    self.default_middleware.process_value(key, value, &mut stylesheet, options)?;
                },
            }
        }

        Ok(stylesheet)
    }
}