1#[cfg(feature = "default-themes")]
16use crate::highlighting::ThemeSet;
17#[cfg(feature = "default-syntaxes")]
18use crate::parsing::SyntaxSet;
19#[cfg(feature = "dump-load")]
20use bincode::deserialize_from;
21#[cfg(feature = "dump-create")]
22use bincode::serialize_into;
23use bincode::Result;
24#[cfg(feature = "dump-load")]
25use flate2::bufread::ZlibDecoder;
26#[cfg(feature = "dump-create")]
27use flate2::write::ZlibEncoder;
28#[cfg(feature = "dump-create")]
29use flate2::Compression;
30#[cfg(feature = "dump-load")]
31use serde::de::DeserializeOwned;
32#[cfg(feature = "dump-create")]
33use serde::ser::Serialize;
34use std::fs::File;
35#[cfg(feature = "dump-load")]
36use std::io::BufRead;
37#[cfg(feature = "dump-create")]
38use std::io::{BufWriter, Write};
39use std::path::Path;
40
41#[cfg(feature = "dump-create")]
45pub fn dump_to_writer<T: Serialize, W: Write>(to_dump: &T, output: W) -> Result<()> {
46 serialize_to_writer_impl(to_dump, output, true)
47}
48
49#[cfg(feature = "dump-create")]
53pub fn dump_binary<T: Serialize>(o: &T) -> Vec<u8> {
54 let mut v = Vec::new();
55 dump_to_writer(o, &mut v).unwrap();
56 v
57}
58
59#[cfg(feature = "dump-create")]
66pub fn dump_to_file<T: Serialize, P: AsRef<Path>>(o: &T, path: P) -> Result<()> {
67 let out = BufWriter::new(File::create(path)?);
68 dump_to_writer(o, out)
69}
70
71#[cfg(feature = "dump-load")]
73pub fn from_reader<T: DeserializeOwned, R: BufRead>(input: R) -> Result<T> {
74 deserialize_from_reader_impl(input, true)
75}
76
77#[cfg(feature = "dump-load")]
81pub fn from_binary<T: DeserializeOwned>(v: &[u8]) -> T {
82 from_reader(v).unwrap()
83}
84
85#[cfg(feature = "dump-load")]
87pub fn from_dump_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T> {
88 let contents = std::fs::read(path)?;
89 from_reader(&contents[..])
90}
91
92#[cfg(feature = "dump-create")]
97pub fn dump_to_uncompressed_file<T: Serialize, P: AsRef<Path>>(o: &T, path: P) -> Result<()> {
98 let out = BufWriter::new(File::create(path)?);
99 serialize_to_writer_impl(o, out, false)
100}
101
102#[cfg(feature = "dump-load")]
105pub fn from_uncompressed_dump_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T> {
106 let contents = std::fs::read(path)?;
107 deserialize_from_reader_impl(&contents[..], false)
108}
109
110#[cfg(feature = "dump-load")]
114pub fn from_uncompressed_data<T: DeserializeOwned>(v: &[u8]) -> Result<T> {
115 deserialize_from_reader_impl(v, false)
116}
117
118#[cfg(feature = "dump-create")]
120fn serialize_to_writer_impl<T: Serialize, W: Write>(
121 to_dump: &T,
122 output: W,
123 use_compression: bool,
124) -> Result<()> {
125 if use_compression {
126 let mut encoder = std::io::BufWriter::new(ZlibEncoder::new(output, Compression::best()));
127 serialize_into(&mut encoder, to_dump)
128 } else {
129 serialize_into(output, to_dump)
130 }
131}
132
133#[cfg(feature = "dump-load")]
135fn deserialize_from_reader_impl<T: DeserializeOwned, R: BufRead>(
136 input: R,
137 use_compression: bool,
138) -> Result<T> {
139 if use_compression {
140 let mut decoder = ZlibDecoder::new(input);
141 deserialize_from(&mut decoder)
142 } else {
143 deserialize_from(input)
144 }
145}
146
147#[cfg(feature = "default-syntaxes")]
148impl SyntaxSet {
149 pub fn load_defaults_nonewlines() -> SyntaxSet {
169 #[cfg(feature = "metadata")]
170 {
171 let mut ps: SyntaxSet =
172 from_uncompressed_data(include_bytes!("../assets/default_nonewlines.packdump"))
173 .unwrap();
174 let metadata = from_binary(include_bytes!("../assets/default_metadata.packdump"));
175 ps.metadata = metadata;
176 ps
177 }
178 #[cfg(not(feature = "metadata"))]
179 {
180 from_uncompressed_data(include_bytes!("../assets/default_nonewlines.packdump")).unwrap()
181 }
182 }
183
184 pub fn load_defaults_newlines() -> SyntaxSet {
191 #[cfg(feature = "metadata")]
192 {
193 let mut ps: SyntaxSet =
194 from_uncompressed_data(include_bytes!("../assets/default_newlines.packdump"))
195 .unwrap();
196 let metadata = from_binary(include_bytes!("../assets/default_metadata.packdump"));
197 ps.metadata = metadata;
198 ps
199 }
200 #[cfg(not(feature = "metadata"))]
201 {
202 from_uncompressed_data(include_bytes!("../assets/default_newlines.packdump")).unwrap()
203 }
204 }
205}
206
207#[cfg(feature = "default-themes")]
208impl ThemeSet {
209 pub fn load_defaults() -> ThemeSet {
216 from_binary(include_bytes!("../assets/default.themedump"))
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 #[cfg(all(
223 feature = "yaml-load",
224 feature = "dump-create",
225 feature = "dump-load",
226 feature = "parsing"
227 ))]
228 #[test]
229 fn can_dump_and_load() {
230 use super::*;
231 use crate::utils::testdata;
232
233 let ss = &*testdata::PACKAGES_SYN_SET;
234
235 let bin = dump_binary(&ss);
236 println!("{:?}", bin.len());
237 let ss2: SyntaxSet = from_binary(&bin[..]);
238 assert_eq!(ss.syntaxes().len(), ss2.syntaxes().len());
239 }
240
241 #[cfg(all(feature = "yaml-load", feature = "dump-create", feature = "dump-load"))]
242 #[test]
243 fn dump_is_deterministic() {
244 use super::*;
245 use crate::parsing::SyntaxSetBuilder;
246 use crate::utils::testdata;
247
248 let ss1 = &*testdata::PACKAGES_SYN_SET;
249 let bin1 = dump_binary(&ss1);
250
251 let mut builder2 = SyntaxSetBuilder::new();
252 builder2
253 .add_from_folder("testdata/Packages", false)
254 .unwrap();
255 let ss2 = builder2.build();
256 let bin2 = dump_binary(&ss2);
257 assert_eq!(bin1.len(), bin2.len());
260 assert_eq!(bin1, bin2);
261 }
262
263 #[cfg(feature = "default-themes")]
264 #[test]
265 fn has_default_themes() {
266 use crate::highlighting::ThemeSet;
267 let themes = ThemeSet::load_defaults();
268 assert!(themes.themes.len() > 4);
269 }
270}