typst_library/loading/
mod.rs1#[path = "cbor.rs"]
4mod cbor_;
5#[path = "csv.rs"]
6mod csv_;
7#[path = "json.rs"]
8mod json_;
9#[path = "read.rs"]
10mod read_;
11#[path = "toml.rs"]
12mod toml_;
13#[path = "xml.rs"]
14mod xml_;
15#[path = "yaml.rs"]
16mod yaml_;
17
18use comemo::Tracked;
19use ecow::EcoString;
20use typst_syntax::Spanned;
21
22pub use self::cbor_::*;
23pub use self::csv_::*;
24pub use self::json_::*;
25pub use self::read_::*;
26pub use self::toml_::*;
27pub use self::xml_::*;
28pub use self::yaml_::*;
29
30use crate::diag::{At, SourceResult};
31use crate::foundations::OneOrMultiple;
32use crate::foundations::{cast, Bytes, Scope, Str};
33use crate::World;
34
35pub(super) fn define(global: &mut Scope) {
37 global.start_category(crate::Category::DataLoading);
38 global.define_func::<read>();
39 global.define_func::<csv>();
40 global.define_func::<json>();
41 global.define_func::<toml>();
42 global.define_func::<yaml>();
43 global.define_func::<cbor>();
44 global.define_func::<xml>();
45 global.reset_category();
46}
47
48#[derive(Debug, Clone, PartialEq, Hash)]
50pub enum DataSource {
51 Path(EcoString),
53 Bytes(Bytes),
55}
56
57cast! {
58 DataSource,
59 self => match self {
60 Self::Path(v) => v.into_value(),
61 Self::Bytes(v) => v.into_value(),
62 },
63 v: EcoString => Self::Path(v),
64 v: Bytes => Self::Bytes(v),
65}
66
67pub trait Load {
69 type Output;
71
72 fn load(&self, world: Tracked<dyn World + '_>) -> SourceResult<Self::Output>;
74}
75
76impl Load for Spanned<DataSource> {
77 type Output = Bytes;
78
79 fn load(&self, world: Tracked<dyn World + '_>) -> SourceResult<Bytes> {
80 self.as_ref().load(world)
81 }
82}
83
84impl Load for Spanned<&DataSource> {
85 type Output = Bytes;
86
87 fn load(&self, world: Tracked<dyn World + '_>) -> SourceResult<Bytes> {
88 match &self.v {
89 DataSource::Path(path) => {
90 let file_id = self.span.resolve_path(path).at(self.span)?;
91 world.file(file_id).at(self.span)
92 }
93 DataSource::Bytes(bytes) => Ok(bytes.clone()),
94 }
95 }
96}
97
98impl Load for Spanned<OneOrMultiple<DataSource>> {
99 type Output = Vec<Bytes>;
100
101 fn load(&self, world: Tracked<dyn World + '_>) -> SourceResult<Vec<Bytes>> {
102 self.as_ref().load(world)
103 }
104}
105
106impl Load for Spanned<&OneOrMultiple<DataSource>> {
107 type Output = Vec<Bytes>;
108
109 fn load(&self, world: Tracked<dyn World + '_>) -> SourceResult<Vec<Bytes>> {
110 self.v
111 .0
112 .iter()
113 .map(|source| Spanned::new(source, self.span).load(world))
114 .collect()
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Hash)]
120pub enum Readable {
121 Str(Str),
123 Bytes(Bytes),
125}
126
127impl Readable {
128 pub fn into_bytes(self) -> Bytes {
129 match self {
130 Self::Bytes(v) => v,
131 Self::Str(v) => Bytes::from_string(v),
132 }
133 }
134
135 pub fn into_source(self) -> DataSource {
136 DataSource::Bytes(self.into_bytes())
137 }
138}
139
140cast! {
141 Readable,
142 self => match self {
143 Self::Str(v) => v.into_value(),
144 Self::Bytes(v) => v.into_value(),
145 },
146 v: Str => Self::Str(v),
147 v: Bytes => Self::Bytes(v),
148}