sixtyfps_compilerlib/
fileaccess.rs

1// Copyright © SixtyFPS GmbH <info@sixtyfps.io>
2// SPDX-License-Identifier: (GPL-3.0-only OR LicenseRef-SixtyFPS-commercial)
3
4use std::borrow::Cow;
5
6#[derive(Clone)]
7pub struct VirtualFile<'a> {
8    pub path: Cow<'a, str>,
9    pub builtin_contents: Option<&'static [u8]>,
10}
11
12impl<'a> VirtualFile<'a> {
13    pub fn read(&self) -> Cow<'static, [u8]> {
14        match self.builtin_contents {
15            Some(static_data) => Cow::Borrowed(static_data),
16            None => Cow::Owned(std::fs::read(self.path.as_ref()).unwrap()),
17        }
18    }
19
20    pub fn is_builtin(&self) -> bool {
21        self.builtin_contents.is_some()
22    }
23}
24
25pub fn load_file<'a>(path: &'a std::path::Path) -> Option<VirtualFile<'static>> {
26    match path.strip_prefix("builtin:/") {
27        Ok(builtin_path) => builtin_library::load_builtin_file(builtin_path),
28        Err(_) => path.exists().then(|| VirtualFile {
29            path: Cow::Owned(path.to_string_lossy().to_string()),
30            builtin_contents: None,
31        }),
32    }
33}
34
35mod builtin_library {
36    include!(env!("SIXTYFPS_WIDGETS_LIBRARY"));
37
38    pub type BuiltinDirectory<'a> = [&'a BuiltinFile<'a>];
39
40    pub struct BuiltinFile<'a> {
41        pub path: &'a str,
42        pub contents: &'static [u8],
43    }
44
45    use super::VirtualFile;
46
47    pub(crate) fn load_builtin_file(
48        builtin_path: &std::path::Path,
49    ) -> Option<VirtualFile<'static>> {
50        let mut components = vec![];
51        for part in builtin_path.iter() {
52            if part == ".." {
53                components.pop();
54            } else if part != "." {
55                components.push(part);
56            }
57        }
58        if let &[folder, file] = components.as_slice() {
59            let library = widget_library().iter().find(|x| x.0 == folder)?.1;
60            library.iter().find_map(|builtin_file| {
61                if builtin_file.path == file {
62                    Some(VirtualFile {
63                        path: builtin_file.path.into(),
64                        builtin_contents: Some(builtin_file.contents),
65                    })
66                } else {
67                    None
68                }
69            })
70        } else {
71            None
72        }
73    }
74}