gayconf/src/lib.rs

139 lines
3 KiB
Rust

// See the end of this file for copyright and license terms.
use std::collections::HashMap;
use std::collections::hash_map::Keys;
use std::str::Chars;
mod lex;
use crate::lex::{Lexer, SyntaxError};
mod parser;
use parser::Parser;
mod ast;
pub struct Config {
nodes: HashMap<String, Node>,
}
impl Config {
pub fn parse(stream: Chars) -> Result<Config, SyntaxError> {
let lexer = Lexer::new(stream);
let parser = Parser::new(lexer);
let mut nodes = HashMap::new();
for nr in parser {
match nr {
Ok(node) => {
let name = node.name.clone();
nodes.insert(name, node);
}
Err(err) => return Err(err),
}
}
Ok(Config { nodes })
}
pub fn keys(&self) -> Keys<String, Node> {
self.nodes.keys()
}
pub fn get_node(&self, name: &str) -> Option<&Node> {
self.nodes.get(name)
}
}
#[derive(Debug)]
pub struct Node {
pub(crate) name: String,
pub(crate) val: NodeVal,
}
#[derive(Debug)]
enum NodeVal {
Bool(bool),
Int(i64),
String(String),
}
impl Node {
pub fn name(&self) -> &str {
&self.name
}
pub fn val_bool(&self) -> Option<&bool> {
match &self.val {
NodeVal::Bool(b) => Some(b),
_ => None,
}
}
pub fn val_int(&self) -> Option<&i64> {
match &self.val {
NodeVal::Int(i) => Some(i),
_ => None,
}
}
pub fn val_str(&self) -> Option<&String> {
match &self.val {
NodeVal::String(s) => Some(s),
_ => None,
}
}
}
pub trait GetNodeVal<T> {
fn get(&self, name: &str) -> Option<&T>;
fn get_or<'a>(&'a self, name: &str, default: &'a T) -> &'a T {
match self.get(name) {
Some(x) => x,
None => default,
}
}
}
impl GetNodeVal<bool> for Config {
fn get(&self, name: &str) -> Option<&bool> {
match &self.get_node(name)?.val {
NodeVal::Bool(b) => Some(b),
_ => None,
}
}
}
impl GetNodeVal<i64> for Config {
fn get(&self, name: &str) -> Option<&i64> {
match &self.get_node(name)?.val {
NodeVal::Int(i) => Some(i),
_ => None,
}
}
}
impl GetNodeVal<String> for Config {
fn get(&self, name: &str) -> Option<&String> {
match &self.get_node(name)?.val {
NodeVal::String(s) => Some(s),
_ => None,
}
}
}
pub trait ConfigError {
fn msg(&self) -> &str;
fn line(&self) -> usize;
fn col(&self) -> usize;
}
// Copyright (C) 2021 Fefie <owo@fef.moe>
// This file is part of gayconf.
//
// gayconf is non-violent software: you can use, redistribute,
// and/or modify it under the terms of the CNPLv6+ as found
// in the LICENSE file in the source code root directory or
// at <https://git.pixie.town/thufie/CNPL>.
//
// gayconf comes with ABSOLUTELY NO WARRANTY, to the extent
// permitted by applicable law. See the CNPL for details.