1
0
Fork 0
AdvenOfCode2022/src/prob7.rs

102 lines
2.0 KiB
Rust

use std::collections::HashMap;
use camino::Utf8PathBuf;
use nom::combinator::all_consuming;
use nom::{
branch::alt,
bytes::complete::{tag, take_while1},
combinator::map,
sequence::{preceded, separated_pair},
Finish, IResult,
};
#[derive(Debug)]
struct Ls;
#[derive(Debug)]
struct Cd(Utf8PathBuf);
#[derive(Debug)]
enum Entry {
Dir(Utf8PathBuf),
File(u64, Utf8PathBuf),
}
#[derive(Debug)]
enum Command {
Ls,
Cd(Utf8PathBuf),
}
#[derive(Debug)]
enum Line {
Command(Command),
Entry(Entry),
}
impl From<Ls> for Command {
fn from(_ls: Ls) -> Self {
Command::Ls
}
}
impl From<Cd> for Command {
fn from(cd: Cd) -> Self {
Command::Cd(cd.0)
}
}
struct Node {
children: HashMap<String, Node>,
size: u32,
}
fn parse_entry(input: &str) -> IResult<&str, Entry> {
let parse_file = map(
separated_pair(nom::character::complete::u64, tag(" "), parse_path),
|(size, path)| Entry::File(size, path),
);
let parse_dir = map(preceded(tag("dir "), parse_path), Entry::Dir);
alt((parse_file, parse_dir))(input)
}
fn parse_path(input: &str) -> IResult<&str, Utf8PathBuf> {
map(
take_while1(|c: char| "abcdefghijklmnopqrstuvwxyz./".contains(c)),
Into::into,
)(input)
}
fn parse_ls(input: &str) -> IResult<&str, Ls> {
map(tag("ls"), |_| Ls)(input)
}
fn parse_cd(input: &str) -> IResult<&str, Cd> {
map(preceded(tag("cd "), parse_path), Cd)(input)
}
fn parse_command(line: &str) -> IResult<&str, Command> {
let (input, _) = tag("$ ")(line)?;
alt((map(parse_ls, Into::into), map(parse_cd, Into::into)))(input)
}
fn parse_line(input: &str) -> IResult<&str, Line> {
alt((
map(parse_command, Line::Command),
map(parse_entry, Line::Entry),
))(input)
}
pub fn solve_part1(content: &str) {
let lines = content.lines().map(|line| {
all_consuming(parse_line)(line)
.finish()
.unwrap_or_else(|err| panic!("{err}"))
.1
});
for line in lines {
println!("{line:?}");
}
}