1use crate::parse::CommandTags;
2use crate::ParserConfig;
3use anyhow::Context;
4use anyhow::Result;
5use std::fs::read_to_string;
6use std::path::{Path, PathBuf};
7
8pub static DEFAULT_TAG_BEGIN: &'static str = "<!--{";
9pub static DEFAULT_TAG_END: &'static str = "}-->";
10pub static DEFAULT_END_COMMAND: &'static str = "end";
11
12#[derive(Clone, Debug, Deserialize, PartialEq)]
13#[serde(default)]
14pub struct Config {
15 pub open_tag: String,
17
18 pub close_tag: String,
20
21 pub end_command: String,
23
24 pub base_dir: String,
26
27 pub files: Vec<String>,
29
30 pub next_dirs: Vec<String>,
32
33 pub depend_dirs: Vec<String>,
35
36 pub out_dir: Option<String>,
38}
39
40impl Default for Config {
41 fn default() -> Self {
42 Config {
43 open_tag: DEFAULT_TAG_BEGIN.to_string(),
44 close_tag: DEFAULT_TAG_END.to_string(),
45 end_command: DEFAULT_END_COMMAND.to_string(),
46 base_dir: "".to_string(),
47 files: vec![],
48 next_dirs: vec![],
49 depend_dirs: vec![],
50 out_dir: None,
51 }
52 }
53}
54
55#[derive(Clone, Debug)]
56pub struct ConfigAndPath {
57 pub config: Config,
58 pub path: PathBuf,
59}
60
61impl ConfigAndPath {
62 pub(crate) fn parent_path(&self) -> Result<PathBuf> {
63 Ok(self
64 .path
65 .parent()
66 .context("Could not access parent directory of config file.")?
67 .to_path_buf())
68 }
69 pub(crate) fn into_parser(self) -> Result<(ParserConfig, Vec<PathBuf>)> {
70 let parent = self.parent_path()?;
71 Ok((
72 ParserConfig {
73 tags: CommandTags::new(self.config.open_tag, self.config.close_tag),
74 end_command: self.config.end_command,
75 base_dir: parent.join(self.config.base_dir),
76 },
77 self.config.files.iter().map(|x| parent.join(x)).collect(),
78 ))
79 }
80}
81impl Config {
82 pub(crate) fn try_from_path<P: AsRef<Path>>(dir: P) -> Result<Self> {
83 let file =
84 read_to_string(dir.as_ref()).with_context(|| format!("Reading {:?}", dir.as_ref()))?;
85 Ok(toml::from_str::<Config>(&file)
86 .context("Error in toml config file")?
87 .into())
88 }
89
90 pub(crate) fn try_from_dir<P: Into<PathBuf>>(dir: P) -> Result<Option<ConfigAndPath>> {
93 let dir = dir.into();
94 let file = dir.join(".md-inc.toml");
95 if file.exists() && file.is_file() {
96 Ok(Some(ConfigAndPath {
97 config: Config::try_from_path(&file)?,
98 path: file,
99 }))
100 } else {
101 Ok(None)
102 }
103 }
104}
105
106#[derive(Clone, Debug, Default, PartialEq)]
107pub struct OutputTo {
108 pub read_only: bool,
109 pub print: bool,
110 pub out_dir: Option<PathBuf>,
111}
112impl OutputTo {
113 pub fn stdout() -> Self {
114 Self {
115 read_only: true,
116 print: true,
117 out_dir: None,
118 }
119 }
120 pub fn file() -> Self {
121 Self {
122 read_only: false,
123 print: false,
124 out_dir: None,
125 }
126 }
127 pub fn different_file<P: Into<PathBuf>>(path: P) -> Self {
128 Self {
129 read_only: false,
130 print: false,
131 out_dir: Some(path.into()),
132 }
133 }
134}