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}