Skip to main content

sequoia_seq/
loader.rs

1use std::path::PathBuf;
2
3use sequoia_style::Theme;
4use sequoia_view::AnyView;
5
6use crate::bindings::HostBindings;
7use crate::error::SeqError;
8use crate::resolve::{FsSource, MapSource, SeqSource, resolve_imports};
9use crate::{check, lower, lower_with, parse_seq_file, resolve_theme};
10
11#[derive(Clone, Debug)]
12pub struct AppMeta {
13    pub title: String,
14
15    pub size: (f64, f64),
16
17    pub theme: Theme,
18}
19
20#[derive(Clone)]
21pub struct LoadedApp {
22    pub meta: AppMeta,
23
24    pub view: AnyView,
25
26    pub files: Vec<PathBuf>,
27}
28
29pub struct SeqLoader;
30
31impl SeqLoader {
32    pub fn load_file(path: &str) -> Result<LoadedApp, SeqError> {
33        let src = read_file(path)?;
34        Self::load_from(path, &src, &FsSource, None)
35    }
36
37    pub fn load_str(file: &str, src: &str) -> Result<LoadedApp, SeqError> {
38        Self::load_from(file, src, &FsSource, None)
39    }
40
41    pub fn load_with(path: &str, bindings: &HostBindings) -> Result<LoadedApp, SeqError> {
42        let src = read_file(path)?;
43        Self::load_from(path, &src, &FsSource, Some(bindings))
44    }
45
46    pub fn load_str_with(
47        file: &str,
48        src: &str,
49        bindings: &HostBindings,
50    ) -> Result<LoadedApp, SeqError> {
51        Self::load_from(file, src, &FsSource, Some(bindings))
52    }
53
54    pub fn load_str_map(
55        file: &str,
56        src: &str,
57        files: &[(&str, &str)],
58    ) -> Result<LoadedApp, SeqError> {
59        Self::load_from(file, src, &MapSource::new(files), None)
60    }
61
62    pub fn load_str_with_map(
63        file: &str,
64        src: &str,
65        files: &[(&str, &str)],
66        bindings: &HostBindings,
67    ) -> Result<LoadedApp, SeqError> {
68        Self::load_from(file, src, &MapSource::new(files), Some(bindings))
69    }
70
71    fn load_from(
72        file: &str,
73        src: &str,
74        source: &dyn SeqSource,
75        bindings: Option<&HostBindings>,
76    ) -> Result<LoadedApp, SeqError> {
77        let seq = parse_seq_file(file, src)?;
78        let resolved = resolve_imports(file, seq, source)?;
79        let app = crate::resolve_seq_calls(resolved.app);
80        check(file, &app)?;
81        let theme = resolve_theme(file, &app)?;
82        let view = match bindings {
83            Some(b) => lower_with(file, &app, b)?,
84            None => lower(file, &app)?,
85        };
86        Ok(LoadedApp {
87            meta: AppMeta {
88                title: app.title.clone(),
89                size: (f64::from(app.size.0), f64::from(app.size.1)),
90                theme,
91            },
92            view,
93            files: resolved.files,
94        })
95    }
96}
97
98fn read_file(path: &str) -> Result<String, SeqError> {
99    std::fs::read_to_string(path)
100        .map_err(|e| SeqError::new(path, 1, 1, format!("cannot be read: {e}")))
101}