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