parent
ee355f088a
commit
79250c9b36
@ -0,0 +1,177 @@
|
||||
//! Formatting specifiers for the config file format
|
||||
use super::*;
|
||||
use sexp::{
|
||||
Sexp,
|
||||
Atom,
|
||||
};
|
||||
|
||||
/// A valid type in the config file
|
||||
#[derive(Debug)]
|
||||
pub enum LispType
|
||||
{
|
||||
List,
|
||||
String,
|
||||
Integer,
|
||||
Float,
|
||||
Atom,
|
||||
}
|
||||
|
||||
impl From<Sexp> for LispType
|
||||
{
|
||||
fn from(from: Sexp) -> Self
|
||||
{
|
||||
match from {
|
||||
Sexp::Atom(atom) => atom.into(),
|
||||
Sexp::List(_) => Self::List
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Atom> for LispType
|
||||
{
|
||||
fn from(from: Atom) -> Self
|
||||
{
|
||||
match from {
|
||||
Atom::F(_) => Self::Float,
|
||||
Atom::I(_) => Self::Integer,
|
||||
Atom::S(_) => Self::String,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Result<T, Error>> for LispType
|
||||
where T: Into<LispType>
|
||||
{
|
||||
fn from(from: Result<T, Error>) -> Self
|
||||
{
|
||||
match from {
|
||||
Ok(value) => value.into(),
|
||||
Err(Error::TypeError{got,..}) => got,
|
||||
_ => unreachable!("you shouldn't use this here"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for LispType
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||
{
|
||||
f.write_str(match self {
|
||||
Self::List => "list",
|
||||
Self::String => "string",
|
||||
Self::Integer => "integer",
|
||||
Self::Float => "float",
|
||||
Self::Atom => "atom",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LispExt
|
||||
{
|
||||
/// Try to get `car` and `cdr`
|
||||
fn try_split<'a>(&'a self) -> Result<(&'a Sexp, &'a [Sexp]), Error>;
|
||||
}
|
||||
|
||||
impl LispExt for Vec<Sexp>
|
||||
{
|
||||
fn try_split<'a>(&'a self) -> Result<(&'a Sexp, &'a [Sexp]), Error>
|
||||
{
|
||||
if self.len() > 1 {
|
||||
Ok((&self[0], &self[1..]))
|
||||
} else if self.len() > 0{
|
||||
Ok((&self[0], &[]))
|
||||
} else {
|
||||
Err(Error::BadLength)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sexp doesn't use try_from(), so...
|
||||
pub trait TryIntoExt: Sized
|
||||
{
|
||||
fn try_into_list(self) -> Result<Vec<Sexp>, Error>;
|
||||
fn try_into_atom(self) -> Result<Atom, Error>;
|
||||
|
||||
fn try_into_string(self) -> Result<String, Error>;
|
||||
fn try_into_int(self) -> Result<i64, Error>;
|
||||
fn try_into_float(self) -> Result<f64, Error>;
|
||||
}
|
||||
|
||||
impl TryIntoExt for Sexp
|
||||
{
|
||||
fn try_into_list(self) -> Result<Vec<Sexp>, Error>
|
||||
{
|
||||
match self {
|
||||
Sexp::List(this) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::List, other)),
|
||||
}
|
||||
}
|
||||
fn try_into_atom(self) -> Result<Atom, Error>
|
||||
{
|
||||
match self {
|
||||
Sexp::Atom(this) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::Atom, other)),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_string(self) -> Result<String, Error>
|
||||
{
|
||||
match self.try_into_atom() {
|
||||
Ok(Atom::S(this)) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::String, other)),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_int(self) -> Result<i64, Error>
|
||||
{
|
||||
match self.try_into_atom() {
|
||||
Ok(Atom::I(this)) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::Integer, other)),
|
||||
}
|
||||
}
|
||||
fn try_into_float(self) -> Result<f64, Error>
|
||||
{
|
||||
match self.try_into_atom() {
|
||||
Ok(Atom::F(this)) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::Float, other)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryIntoExt for Atom
|
||||
{
|
||||
#[inline]
|
||||
fn try_into_list(self) -> Result<Vec<Sexp>, Error>
|
||||
{
|
||||
Err(Error::bad_type(LispType::List, self))
|
||||
}
|
||||
#[inline]
|
||||
fn try_into_atom(self) -> Result<Atom, Error>
|
||||
{
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn try_into_string(self) -> Result<String, Error>
|
||||
{
|
||||
match self {
|
||||
Atom::S(this) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::String, other)),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_int(self) -> Result<i64, Error>
|
||||
{
|
||||
match self {
|
||||
Atom::I(this) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::Integer, other)),
|
||||
}
|
||||
}
|
||||
fn try_into_float(self) -> Result<f64, Error>
|
||||
{
|
||||
match self {
|
||||
Atom::F(this) => Ok(this),
|
||||
other => Err(Error::bad_type(LispType::Float, other)),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue