lore for collections | 最简实现过程

16 阅读1分钟

不算空行,基础的行类型只有三种。

// src/line.rs
use std::fmt::{Display, Formatter};

pub struct Line {
    pub indent: usize,
    pub content: Content,
}

pub enum Content {
    Atom(String),
    Link(String, String),
    Domain(String)
}

impl Display for Line {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let spaces = "  ".repeat(self.indent);
        match &self.content {
            Content::Atom(atom) => write!(f, "{}{}", spaces, atom),
            Content::Link(key, value) => write!(f, "{}{} = {}", spaces, key, value),
            Content::Domain(domain) => write!(f, "{}+ {}", spaces, domain)
        }
    }
}

输入的文件会被拆成若干行。

// src/input_lore.rs
use std::path::Path;
use std::fs;
use crate::line::Line;

pub fn input_lore_file(path: &Path) -> String {
    fs::read_to_string(path).unwrap()
}

pub fn parse(input: String) -> Vec<Line> {
    input
        .as_str()
        .split('\n')
        .filter(|line| !line.trim().is_empty())
        .map(crate::parser::parse_line)
        .collect()
}

借助标准库的一些方法实现每行的字符解析。

// src/parse.rs
use std::path::Path;
use std::fs;
use crate::line::Line;

pub fn input_lore_file(path: &Path) -> String {
    fs::read_to_string(path).unwrap()
}

pub fn parse(input: String) -> Vec<Line> {
    input
        .as_str()
        .split('\n')
        .filter(|line| !line.trim().is_empty())
        .map(crate::parser::parse_line)
        .collect()
}

入口程序如此。

// src/main.rs
use std::path::Path;
use crate::input_lore::input_lore_file;
use crate::input_lore::parse;

mod line;
mod parser;
mod input_lore;

fn main() {
    let content: String = input_lore_file(Path::new("..\test\basic.lore"));
    let target = parse(content);
    
    for line in &target {
        println!("{}", line);
    }
}

测试如此。

image.png