Skip to main content

slime/
lib.rs

1extern crate fs_extra;
2extern crate handlebars;
3extern crate serde;
4extern crate serde_json;
5extern crate toml;
6#[macro_use]
7extern crate failure;
8
9use serde_json::value::Value as SerdeJson;
10use toml::Value as Toml;
11use serde::ser::Serialize;
12use handlebars::Handlebars;
13use failure::Error;
14
15pub mod template;
16pub mod data;
17pub mod generate;
18
19
20/// Rust library for fast prototyping and creating static websites.
21/// Use handlebars to handle html parts.
22/// Uses json and toml formats for data passed into templates.
23/// Flexible design allows to create any type of static website.
24
25/// Creating new project:
26/// Create new binary crate with
27/// ```
28/// cargo new --bin crate_name
29/// ```
30/// Open crate folder and run
31/// curl -s https://raw.githubusercontent.com/jaroslaw-weber/slime/master/init_slime.sh | bash
32/// This will download deployment scripts and create some folders.
33/// It will also create example files.
34
35/// Wrapper for creating a static websites.
36/// Load templates and helps with loading and inserting data into templates.
37pub struct Slime<'a> {
38    /// cached config
39    config: Config<'a>,
40    /// cached templates
41    templates: Option<Handlebars>,
42}
43
44impl<'a> Slime<'a> {
45    /// Create new wrapper with custom config.
46    pub fn new(config: Config<'a>) -> Slime<'a> {
47        Slime {
48            config: config,
49            templates: None,
50        }
51    }
52
53    /// Load templates (need to run only once)
54    pub fn initialize(&mut self) -> Result<(), Error> {
55        let hb: Handlebars = template::load_all(&self.config)?;
56        self.templates = Some(hb);
57        Ok(())
58    }
59
60    /// Load json data from data folder.
61    /// Default file extension is ".json" if not specified.
62    pub fn load_json_data(&self, file_name: &str) -> Result<SerdeJson, Error> {
63        data::load_json(self.config.data_path, file_name)
64    }
65
66    /// Load toml data from data folder. 
67    /// Default file extension is ".toml" if not specified.
68    pub fn load_toml_data(&self, file_name: &str) -> Result<Toml, Error> {
69        data::load_toml(self.config.data_path, file_name)
70    }
71
72
73    /// Generate file. If filename has no extension then default extension is added (.html)
74    pub fn generate<T: Serialize>(
75        &self,
76        template: &str,
77        file_name: &str,
78        data: &T,
79    ) -> Result<(), Error> {
80        match &self.templates {
81            &Some(ref hb) => {
82                generate::generate(
83                    &hb,
84                    template,
85                    data,
86                    self.config.generated_path,
87                    file_name,
88                )?;
89                Ok(())
90            }
91            &None => bail!("templates not loaded! use Slime::initialize()"),
92        }
93    }
94
95}
96
97impl<'a> Default for Slime<'a> {
98    fn default() -> Slime<'a> {
99        Slime::new(Config::default())
100    }
101}
102
103/// Folders paths config file.
104pub struct Config<'a> {
105    data_path: &'a str,
106    generated_path: &'a str,
107    templates_path: &'a str,
108}
109
110impl<'a> Config<'a> {
111    pub fn new(data_path: &'a str, generated_path: &'a str, templates_path: &'a str) -> Config<'a> {
112        Config {
113            data_path: data_path,
114            generated_path: generated_path,
115            templates_path: templates_path,
116        }
117    }
118}
119
120/// Default folder paths (working with installation script)
121impl<'a> Default for Config<'a> {
122    fn default() -> Config<'a> {
123        Config {
124            data_path: "data",
125            generated_path: "generated",
126            templates_path: "templates",
127        }
128    }
129}
130
131/// does filename has extension in it?
132fn has_ext(file_name: &str)-> bool
133{
134    file_name.contains(".")
135}
136
137fn get_filename_with_ext(file_name: &str, extension: &str) -> String
138{
139    match has_ext(file_name)
140    {
141        true => file_name.to_string(),
142        false => format!("{}.{}", file_name, extension)
143    }
144}