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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
mod runner;
use crate::runner::{Runner};
mod hovercraft_runner;
use crate::hovercraft_runner::HovercraftRunner;
mod terminal_runner;
use crate::terminal_runner::TerminalRunner;
mod gui_runner;
use crate::gui_runner::GuiRunner;
mod bema;
use crate::bema::{Bema, SlideItem, Slide};

use std::env;

use crossterm::Result;

pub fn slides(f: fn(Bema) -> Bema) -> Bema {
    f(Bema { 
        slides: vec![],
    })
}

impl Slide {
}


impl Bema {
    pub fn slide(mut self, title: &str, f: fn(Slide) -> Slide) -> Bema {

        let s = Slide {
            title: String::from(title),
            items: vec![],
        };
        self.slides.push(f(s));
        self
    }

    pub fn run(&self) -> Result<()> {
        if env::args().len() == 2 {
            let args : Vec<String> = env::args().collect();
            match args[1].as_str() {
                "hovercraft" => HovercraftRunner { }.run(&self)?,
                "gui" => GuiRunner { }.run(&self)?,
                _ => {}
            }
        } else {
            TerminalRunner { }.run(&self)?;
        }
        Ok(())
    }
}

pub struct BoxedSlideItems {
    items: Vec<SlideItem>,
}

impl BoxedSlideItems {
    pub fn push(mut self, item: SlideItem) -> BoxedSlideItems {
        self.items.push(item);
        self
    }

    pub fn text(self, s: &str) -> BoxedSlideItems {
        self.push(SlideItem::Text { text: String::from(s) })
    }

    pub fn t(self, s: &str) -> BoxedSlideItems {
        self.text(s)
    }

    pub fn code(self, extension: &str, source: &str) -> BoxedSlideItems {
        self.push(SlideItem::Code { extension: String::from(extension), source: String::from(source) })
    }

    pub fn image(self, image: Vec<u8>, extension: &str, width: Option<usize>) -> BoxedSlideItems {
        self.push(SlideItem::Image { image, extension: String::from(extension), width })
    }

    pub fn cols(self, f: fn(BoxedSlideItems) -> BoxedSlideItems) -> BoxedSlideItems {
        self.push(SlideItem::Cols { items: f(BoxedSlideItems { items: vec![]}).items })
    }

    pub fn rows(self, f: fn(BoxedSlideItems) -> BoxedSlideItems) -> BoxedSlideItems {
        self.push(SlideItem::Rows { items: f(BoxedSlideItems { items: vec![]}).items })
    }
}

impl Slide {
    pub fn push(mut self, item: SlideItem) -> Slide {
        self.items.push(item);
        self
    }

    pub fn text(self, s: &str) -> Slide {
        self.push(SlideItem::Text { text: String::from(s) })
    }

    pub fn t(self, s: &str) -> Slide {
        self.text(s)
    }

    pub fn code(self, extension: &str, source: &str) -> Slide {
        self.push(SlideItem::Code { extension: String::from(extension), source: String::from(source) })
    }

    pub fn image(self, image: Vec<u8>, extension: &str, width: Option<usize>) -> Slide {
        self.push(SlideItem::Image { image, extension: String::from(extension), width })
    }

    pub fn cols(self, f: fn(BoxedSlideItems) -> BoxedSlideItems) -> Slide {
        self.push(SlideItem::Cols { items: f(BoxedSlideItems { items: vec![]}).items })
    }

    pub fn rows(self, f: fn(BoxedSlideItems) -> BoxedSlideItems) -> Slide {
        self.push(SlideItem::Rows { items: f(BoxedSlideItems { items: vec![]}).items })
    }
}