use bincode::Result;
#[cfg(feature = "dump-load")]
use bincode::deserialize_from;
#[cfg(feature = "dump-create")]
use bincode::serialize_into;
use std::fs::File;
#[cfg(feature = "dump-load")]
use std::io::{BufRead};
#[cfg(feature = "dump-create")]
use std::io::{BufWriter, Write};
#[cfg(all(feature = "default-syntaxes"))]
use crate::parsing::SyntaxSet;
#[cfg(all(feature = "default-themes"))]
use crate::highlighting::ThemeSet;
use std::path::Path;
#[cfg(feature = "dump-create")]
use flate2::write::ZlibEncoder;
#[cfg(feature = "dump-load")]
use flate2::bufread::ZlibDecoder;
#[cfg(feature = "dump-create")]
use flate2::Compression;
#[cfg(feature = "dump-create")]
use serde::Serialize;
#[cfg(feature = "dump-load")]
use serde::de::DeserializeOwned;
#[cfg(feature = "dump-create")]
pub fn dump_to_writer<T: Serialize, W: Write>(to_dump: &T, output: W) -> Result<()> {
serialize_to_writer_impl(to_dump, output, true)
}
#[cfg(feature = "dump-create")]
pub fn dump_binary<T: Serialize>(o: &T) -> Vec<u8> {
let mut v = Vec::new();
dump_to_writer(o, &mut v).unwrap();
v
}
#[cfg(feature = "dump-create")]
pub fn dump_to_file<T: Serialize, P: AsRef<Path>>(o: &T, path: P) -> Result<()> {
let out = BufWriter::new(File::create(path)?);
dump_to_writer(o, out)
}
#[cfg(feature = "dump-load")]
pub fn from_reader<T: DeserializeOwned, R: BufRead>(input: R) -> Result<T> {
deserialize_from_reader_impl(input, true)
}
#[cfg(feature = "dump-load")]
pub fn from_binary<T: DeserializeOwned>(v: &[u8]) -> T {
from_reader(v).unwrap()
}
#[cfg(feature = "dump-load")]
pub fn from_dump_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T> {
let contents = std::fs::read(path)?;
from_reader(&contents[..])
}
#[cfg(feature = "dump-create")]
pub fn dump_to_uncompressed_file<T: Serialize, P: AsRef<Path>>(o: &T, path: P) -> Result<()> {
let out = BufWriter::new(File::create(path)?);
serialize_to_writer_impl(o, out, false)
}
#[cfg(feature = "dump-load")]
pub fn from_uncompressed_dump_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T> {
let contents = std::fs::read(path)?;
deserialize_from_reader_impl(&contents[..], false)
}
#[cfg(feature = "dump-load")]
pub fn from_uncompressed_data<T: DeserializeOwned>(v: &[u8]) -> Result<T> {
deserialize_from_reader_impl(v, false)
}
#[cfg(feature = "dump-create")]
fn serialize_to_writer_impl<T: Serialize, W: Write>(to_dump: &T, output: W, use_compression: bool) -> Result<()> {
if use_compression {
let mut encoder = ZlibEncoder::new(output, Compression::best());
serialize_into(&mut encoder, to_dump)
} else {
serialize_into(output, to_dump)
}
}
#[cfg(feature = "dump-load")]
fn deserialize_from_reader_impl<T: DeserializeOwned, R: BufRead>(input: R, use_compression: bool) -> Result<T> {
if use_compression {
let mut decoder = ZlibDecoder::new(input);
deserialize_from(&mut decoder)
} else {
deserialize_from(input)
}
}
#[cfg(feature = "default-syntaxes")]
impl SyntaxSet {
pub fn load_defaults_nonewlines() -> SyntaxSet {
#[cfg(feature = "metadata")]
{
let mut ps: SyntaxSet = from_uncompressed_data(include_bytes!("../assets/default_nonewlines.packdump")).unwrap();
let metadata = from_binary(include_bytes!("../assets/default_metadata.packdump"));
ps.metadata = metadata;
ps
}
#[cfg(not(feature = "metadata"))]
{
from_uncompressed_data(include_bytes!("../assets/default_nonewlines.packdump")).unwrap()
}
}
pub fn load_defaults_newlines() -> SyntaxSet {
#[cfg(feature = "metadata")]
{
let mut ps: SyntaxSet = from_uncompressed_data(include_bytes!("../assets/default_newlines.packdump")).unwrap();
let metadata = from_binary(include_bytes!("../assets/default_metadata.packdump"));
ps.metadata = metadata;
ps
}
#[cfg(not(feature = "metadata"))]
{
from_uncompressed_data(include_bytes!("../assets/default_newlines.packdump")).unwrap()
}
}
}
#[cfg(all(feature = "default-themes"))]
impl ThemeSet {
pub fn load_defaults() -> ThemeSet {
from_binary(include_bytes!("../assets/default.themedump"))
}
}
#[cfg(test)]
mod tests {
#[cfg(all(feature = "yaml-load", feature = "dump-create", feature = "dump-load", feature = "parsing"))]
#[test]
fn can_dump_and_load() {
use super::*;
use crate::parsing::SyntaxSetBuilder;
let mut builder = SyntaxSetBuilder::new();
builder.add_from_folder("testdata/Packages", false).unwrap();
let ss = builder.build();
let bin = dump_binary(&ss);
println!("{:?}", bin.len());
let ss2: SyntaxSet = from_binary(&bin[..]);
assert_eq!(ss.syntaxes().len(), ss2.syntaxes().len());
}
#[cfg(all(feature = "yaml-load", feature = "dump-create", feature = "dump-load"))]
#[test]
fn dump_is_deterministic() {
use super::*;
use crate::parsing::SyntaxSetBuilder;
let mut builder1 = SyntaxSetBuilder::new();
builder1.add_from_folder("testdata/Packages", false).unwrap();
let ss1 = builder1.build();
let bin1 = dump_binary(&ss1);
let mut builder2 = SyntaxSetBuilder::new();
builder2.add_from_folder("testdata/Packages", false).unwrap();
let ss2 = builder2.build();
let bin2 = dump_binary(&ss2);
assert_eq!(bin1.len(), bin2.len());
assert_eq!(bin1, bin2);
}
#[cfg(feature = "default-themes")]
#[test]
fn has_default_themes() {
use crate::highlighting::ThemeSet;
let themes = ThemeSet::load_defaults();
assert!(themes.themes.len() > 4);
}
}