1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3
4use std::fs::canonicalize;
5use std::path::{Path, PathBuf};
6
7pub use encoding::*;
8pub use error::*;
9pub use sink::Sink;
10pub use source::{Source, SourceReader};
11
12pub mod de;
13mod encoding;
14mod error;
15pub mod jq;
16pub mod key;
17mod parsers;
18pub mod ser;
19mod sink;
20mod source;
21mod value;
22
23trait PathExt {
24 fn relative_to<P>(&self, path: P) -> Option<PathBuf>
25 where
26 P: AsRef<Path>;
27
28 fn relative_to_cwd(&self) -> Option<PathBuf> {
29 std::env::current_dir()
30 .ok()
31 .and_then(|base| self.relative_to(base))
32 }
33
34 fn glob_files(&self, pattern: &str) -> Result<Vec<PathBuf>>;
35}
36
37impl<T> PathExt for T
38where
39 T: AsRef<Path>,
40{
41 fn relative_to<P>(&self, base: P) -> Option<PathBuf>
42 where
43 P: AsRef<Path>,
44 {
45 let (path, base) = (canonicalize(self).ok()?, canonicalize(base).ok()?);
46 pathdiff::diff_paths(path, base)
47 }
48
49 fn glob_files(&self, pattern: &str) -> Result<Vec<PathBuf>> {
50 let full_pattern = self.as_ref().join(pattern);
51
52 glob::glob(&full_pattern.to_string_lossy())
53 .map_err(|err| Error::glob_pattern(full_pattern.display(), err))?
54 .filter_map(|result| match result {
55 Ok(path) => path.is_file().then(|| Ok(path)),
56 Err(err) => Some(Err(err.into_error().into())),
57 })
58 .collect()
59 }
60}