Begin implemetation of config parser

master
not manx 4 years ago
parent 8fdd1a6353
commit f27dceed24
Signed by: C-xC-c
GPG Key ID: F52ED472284EF2F4

1
Cargo.lock generated

@ -533,6 +533,7 @@ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
"lazy_static", "lazy_static",
"memchr",
"mio", "mio",
"num_cpus", "num_cpus",
"pin-project-lite", "pin-project-lite",

@ -12,7 +12,7 @@ default = ["threaded"]
threaded = ["tokio/rt-threaded"] threaded = ["tokio/rt-threaded"]
[dependencies] [dependencies]
tokio = {version = "0.2", features=["time", "macros", "io-driver", "sync", "rt-core"]} tokio = {version = "0.2", features=["time", "macros", "io-driver", "sync", "rt-core", "fs"]}
notify = "4.0" notify = "4.0"
futures= "0.3" futures= "0.3"
sexp = "1.1" sexp = "1.1"

@ -2,13 +2,16 @@
use super::*; use super::*;
use std::{ use std::{
io, io,
path::PathBuf,
}; };
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
IO(io::Error), IO(io::Error),
Syntax(sexp::Error), Syntax(sexp::Error),
NotFound(PathBuf),
InvalidUtf8,
InvalidSexp,
Unknown, Unknown,
} }
@ -30,7 +33,9 @@ impl std::fmt::Display for Error
match self { match self {
Self::IO(io) => write!(f, "i/o error: {}", io), Self::IO(io) => write!(f, "i/o error: {}", io),
Self::Syntax(sy) => write!(f, "s-expression syntax error: {}", sy), Self::Syntax(sy) => write!(f, "s-expression syntax error: {}", sy),
Self::NotFound(path) => write!(f, "File not found: {:?}", path),
Self::InvalidUtf8 => write!(f, "Invalid UTF8 decoded string or some such"),
Self::InvalidSexp => write!(f, "Invalid s-expression"),
_ => write!(f, "unknown error") _ => write!(f, "unknown error")
} }
} }
@ -40,7 +45,7 @@ impl From<io::Error> for Error
{ {
fn from(from: io::Error) -> Self fn from(from: io::Error) -> Self
{ {
Self::IO(from) Self::IO(from)
} }
} }
@ -48,7 +53,7 @@ impl From<sexp::Error> for Error
{ {
fn from(from: sexp::Error) -> Self fn from(from: sexp::Error) -> Self
{ {
Self::Syntax(from) Self::Syntax(from)
} }
} }
@ -56,6 +61,14 @@ impl From<Box<sexp::Error>> for Error
{ {
fn from(from: Box<sexp::Error>) -> Self fn from(from: Box<sexp::Error>) -> Self
{ {
Self::Syntax(*from) Self::Syntax(*from)
}
}
impl From<std::str::Utf8Error> for Error
{
fn from(from: std::str::Utf8Error) -> Self
{
Self::InvalidUtf8
} }
} }

@ -33,6 +33,8 @@ pub struct Config
pub job_dirs: Vec<PathBuf>, pub job_dirs: Vec<PathBuf>,
/// The rules for users /// The rules for users
pub user_rules: Vec<UserRule>, pub user_rules: Vec<UserRule>,
/// Enable debug
pub debug: bool,
} }
impl Default for Config impl Default for Config
@ -40,6 +42,6 @@ impl Default for Config
#[inline] #[inline]
fn default() -> Self fn default() -> Self
{ {
Self{job_dirs: Vec::new(), user_rules: Vec::new()} Self{job_dirs: Vec::new(), user_rules: Vec::new(), debug: false}
} }
} }

@ -40,5 +40,4 @@ pub struct Job
what: Command, what: Command,
} }
const DEFAULT_JOB_DIR: &str = "/etc/rori.kron"; const DEFAULT_JOB_DIR: &str = "/etc/rori.kron";

@ -3,8 +3,8 @@ use std::{
str, str,
fmt, fmt,
path::{ path::{
PathBuf, PathBuf,
Path, Path,
}, },
}; };
@ -20,9 +20,9 @@ pub use global::*;
/// Parse a single config file /// Parse a single config file
#[inline] #[inline]
pub fn parse_global_single(path: impl AsRef<Path>) -> Result<Config, error::Error> pub async fn parse_global_single(path: impl AsRef<Path>) -> Result<Config, error::Error>
{ {
let mut cfg = Config::default(); let mut cfg = Config::default();
parse::global(&mut cfg, path)?; parse::global(&mut cfg, path).await?;
Ok(cfg) Ok(cfg)
} }

@ -1,10 +1,74 @@
//! Parses the config files //! Parses the config files
use super::*; use super::*;
use tokio::fs::File;
use tokio::prelude::*;
use sexp::{
parse,
Sexp,
Atom,
};
fn get_atom_string<'a, T>(maybe_atom: T) -> Result<&'a String, Error>
where T: AsRef<Sexp> + 'a
{
match maybe_atom.as_ref() {
Sexp::Atom(Atom::S(string)) => Ok(string),
_ => Err(Error::InvalidSexp),
}
}
fn new_job(to: &mut Config, cdr: &[Sexp]) -> Result<(), Error> {
to.job_dirs.push(PathBuf::from(get_atom_string(&cdr[0])?));
Ok(())
}
/// Parse a single config file /// Parse a single config file
pub fn global(to: &mut Config, path: impl AsRef<Path>) -> Result<(), error::Error> pub async fn global(to: &mut Config, path: impl AsRef<Path>) -> Result<(), error::Error>
{ {
let path = path.as_ref(); let path = path.as_ref();
todo!(); if path.exists() {
let mut file = File::open(path).await?;
let mut contents = vec![];
file.read_to_end(&mut contents).await?;
let parsed = sexp::parse(std::str::from_utf8(&contents[..])?)?;
if let Sexp::List(sexp) = parsed {
for sexp in sexp.into_iter() {
if let Sexp::List(sexp) = sexp {
let car = &sexp[0];
let cdr = &sexp[1..];
match car {
Sexp::List(_) => return Err(Error::InvalidSexp),
Sexp::Atom(car) => {
if let Atom::S(car) = car {
match car.to_lowercase().trim() {
"jobs-dir" => new_job(to, cdr),
"debug" => new_job(to, cdr),
"allow" => new_job(to, cdr),
"deny" => new_job(to, cdr),
_ => return Err(Error::Unknown),
}?;
} else {
return Err(Error::InvalidSexp);
}
}
}
}
else {
return Err(Error::InvalidSexp);
}
}
} else {
return Err(Error::InvalidSexp);
}
Ok(())
} else {
return Err(Error::NotFound(path.to_owned()));
}
} }

@ -4,8 +4,8 @@ use super::*;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use tokio::{ use tokio::{
sync::{ sync::{
RwLock, RwLock,
mpsc, mpsc,
}, },
task, task,
}; };

@ -2,12 +2,12 @@
use std::{ use std::{
fmt::{ fmt::{
self, self,
Display, Display,
}, },
io::{ io::{
self, self,
Write, Write,
}, },
}; };
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;

@ -29,7 +29,7 @@ async fn do_thing_every() -> Result<(mpsc::Sender<()>, task::JoinHandle<()>), Bo
let (tx, mut rx) = mpsc::channel(16); let (tx, mut rx) = mpsc::channel(16);
let handle = tokio::spawn(async move { let handle = tokio::spawn(async move {
println!("starting?"); println!("starting?");
loop { loop {
let mut tick = interval.tick(); let mut tick = interval.tick();
@ -59,15 +59,17 @@ async fn do_thing_every() -> Result<(mpsc::Sender<()>, task::JoinHandle<()>), Bo
async fn main() -> Result<(), Box<dyn std::error::Error>> { async fn main() -> Result<(), Box<dyn std::error::Error>> {
log::init(Default::default()); log::init(Default::default());
debug!("Initialised"); debug!("Initialised");
println!("{:?}", config::parse_global_single("/home/manx/flon.txt").await.expect("Waaaaaah"));
let (mut tx, h) = do_thing_every().await?; //let (mut tx, h) = do_thing_every().await?;
loop { // loop {
time::delay_for(Duration::from_secs(6)).await; // time::delay_for(Duration::from_secs(6)).await;
tx.send(()).await?; // tx.send(()).await?;
} // }
h.await?; // h.await?;
Ok(()) Ok(())
} }

Loading…
Cancel
Save