Format files properly again
I forgot to include the includes and time zone commands
This commit is contained in:
parent
d7df47eba4
commit
2c7aa78d08
5 changed files with 72 additions and 23 deletions
51
src/files.rs
51
src/files.rs
|
|
@ -11,9 +11,21 @@ pub mod commands;
|
||||||
mod format;
|
mod format;
|
||||||
mod parse;
|
mod parse;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct LoadedFile {
|
||||||
|
file: File,
|
||||||
|
dirty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoadedFile {
|
||||||
|
pub fn new(file: File) -> Self {
|
||||||
|
Self { file, dirty: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Files {
|
pub struct Files {
|
||||||
files: HashMap<PathBuf, File>,
|
files: HashMap<PathBuf, LoadedFile>,
|
||||||
timezone: Tz,
|
timezone: Tz,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +54,7 @@ impl Files {
|
||||||
Ok(Self { files, timezone })
|
Ok(Self { files, timezone })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_file(files: &mut HashMap<PathBuf, File>, path: &Path) -> Result<()> {
|
fn load_file(files: &mut HashMap<PathBuf, LoadedFile>, path: &Path) -> Result<()> {
|
||||||
let canon_path = path.canonicalize()?;
|
let canon_path = path.canonicalize()?;
|
||||||
if files.contains_key(&canon_path) {
|
if files.contains_key(&canon_path) {
|
||||||
// We've already loaded this exact file.
|
// We've already loaded this exact file.
|
||||||
|
|
@ -53,31 +65,34 @@ impl Files {
|
||||||
let file = parse::parse(path, &content)?;
|
let file = parse::parse(path, &content)?;
|
||||||
let includes = file.includes.clone();
|
let includes = file.includes.clone();
|
||||||
|
|
||||||
files.insert(canon_path, file);
|
files.insert(canon_path, LoadedFile::new(file));
|
||||||
|
|
||||||
for include in includes {
|
for include in includes {
|
||||||
Self::load_file(files, &include)?;
|
// Since we've successfully opened the file, its name can't be the
|
||||||
|
// root directory or empty string and must thus have a parent.
|
||||||
|
let include_path = path.parent().unwrap().join(include);
|
||||||
|
Self::load_file(files, &include_path)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn determine_timezone(files: &HashMap<PathBuf, File>) -> Result<Tz> {
|
fn determine_timezone(files: &HashMap<PathBuf, LoadedFile>) -> Result<Tz> {
|
||||||
let mut found: Option<(PathBuf, String)> = None;
|
let mut found: Option<(PathBuf, String)> = None;
|
||||||
|
|
||||||
for file in files.values() {
|
for file in files.values() {
|
||||||
if let Some(file_tz) = &file.timezone {
|
if let Some(file_tz) = &file.file.timezone {
|
||||||
if let Some((found_name, found_tz)) = &found {
|
if let Some((found_name, found_tz)) = &found {
|
||||||
if found_tz != file_tz {
|
if found_tz != file_tz {
|
||||||
return Err(Error::TzConflict {
|
return Err(Error::TzConflict {
|
||||||
file1: found_name.clone(),
|
file1: found_name.clone(),
|
||||||
tz1: found_tz.clone(),
|
tz1: found_tz.clone(),
|
||||||
file2: file.name.clone(),
|
file2: file.file.name.clone(),
|
||||||
tz2: file_tz.clone(),
|
tz2: file_tz.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
found = Some((file.name.clone(), file_tz.clone()));
|
found = Some((file.file.name.clone(), file_tz.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,6 +104,26 @@ impl Files {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn save(&self) -> Result<()> {
|
||||||
|
for (path, file) in &self.files {
|
||||||
|
if file.dirty {
|
||||||
|
Self::save_file(path, &file.file)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_file(path: &Path, file: &File) -> Result<()> {
|
||||||
|
fs::write(path, &format!("{}", file))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mark_all_dirty(&mut self) {
|
||||||
|
for (_, file) in self.files.iter_mut() {
|
||||||
|
file.dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn now(&self) -> DateTime<&Tz> {
|
pub fn now(&self) -> DateTime<&Tz> {
|
||||||
Utc::now().with_timezone(&&self.timezone)
|
Utc::now().with_timezone(&&self.timezone)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ pub enum Command {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
pub name: PathBuf,
|
pub name: PathBuf,
|
||||||
pub includes: Vec<PathBuf>,
|
pub includes: Vec<String>,
|
||||||
pub timezone: Option<String>,
|
pub timezone: Option<String>,
|
||||||
pub commands: Vec<Command>,
|
pub commands: Vec<Command>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -273,14 +273,28 @@ impl fmt::Display for Command {
|
||||||
|
|
||||||
impl fmt::Display for File {
|
impl fmt::Display for File {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut commands = self.commands.iter();
|
let mut empty = true;
|
||||||
if let Some(command) = commands.next() {
|
for include in &self.includes {
|
||||||
write!(f, "{}", command)?;
|
writeln!(f, "INCLUDE {}", include)?;
|
||||||
for command in commands {
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(tz) = &self.timezone {
|
||||||
|
if !empty {
|
||||||
writeln!(f)?;
|
writeln!(f)?;
|
||||||
|
}
|
||||||
|
writeln!(f, "TIMEZONE {}", tz)?;
|
||||||
|
empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for command in &self.commands {
|
||||||
|
if !empty {
|
||||||
|
writeln!(f)?;
|
||||||
|
}
|
||||||
write!(f, "{}", command)?;
|
write!(f, "{}", command)?;
|
||||||
|
empty = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -706,12 +706,7 @@ fn parse_command(p: Pair<Rule>, file: &mut File) -> Result<()> {
|
||||||
|
|
||||||
let p = p.into_inner().next().unwrap();
|
let p = p.into_inner().next().unwrap();
|
||||||
match p.as_rule() {
|
match p.as_rule() {
|
||||||
Rule::include => {
|
Rule::include => file.includes.push(parse_include(p)),
|
||||||
// Since we've successfully opened the file, its name can't be the
|
|
||||||
// root directory or empty string and must thus have a parent.
|
|
||||||
let parent = file.name.parent().unwrap();
|
|
||||||
file.includes.push(parent.join(parse_include(p)));
|
|
||||||
}
|
|
||||||
Rule::timezone => match file.timezone {
|
Rule::timezone => match file.timezone {
|
||||||
None => file.timezone = Some(parse_timezone(p)),
|
None => file.timezone = Some(parse_timezone(p)),
|
||||||
Some(_) => fail(p.as_span(), "cannot set timezone multiple times")?,
|
Some(_) => fail(p.as_span(), "cannot set timezone multiple times")?,
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,12 @@ pub struct Opt {
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
let files = Files::load(&opt.file)?;
|
|
||||||
|
let mut files = Files::load(&opt.file)?;
|
||||||
println!("{}", files.now().format("%F %T %Z"));
|
println!("{}", files.now().format("%F %T %Z"));
|
||||||
|
|
||||||
|
files.mark_all_dirty();
|
||||||
|
files.save()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue