~cdv/sexprs

acdd1343234c7218d3b595e00741a971b0baf541 — Chris Vittal 7 months ago 3f2322a
wip
5 files changed, 536 insertions(+), 1 deletions(-)

M Cargo.toml
M src/de.rs
A src/error.rs
M src/lib.rs
M src/ser.rs
M Cargo.toml => Cargo.toml +1 -0
@@ 12,3 12,4 @@ readme = "README.md"

[dependencies]
serde = "1"
itoa = "0.4"

M src/de.rs => src/de.rs +1 -0
@@ 0,0 1,1 @@


A src/error.rs => src/error.rs +139 -0
@@ 0,0 1,139 @@
use std::{fmt, io, str::FromStr};

use serde::ser;

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Error {
    inner: Box<ErrorImpl>,
}

#[derive(Debug)]
struct ErrorImpl {
    code: ErrorCode,
    line: usize,
    column: usize,
}

#[derive(Debug)]
pub(crate) enum ErrorCode {
    Message(Box<str>),

    Io(io::Error),
}

impl fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::Message(m) => fmt::Display::fmt(m, f),
            Self::Io(e) => fmt::Display::fmt(e, f),
        }
    }
}

impl fmt::Display for ErrorImpl {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.line == 0 {
            fmt::Display::fmt(&self.code, f)
        } else {
            write!(
                f,
                "{} at line {}, column {}",
                self.code, self.line, self.column
            )
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.inner, f)
    }
}

impl ser::Error for Error {
    fn custom<T: fmt::Display>(msg: T) -> Self {
        make_error(msg.to_string())
    }
}

impl std::error::Error for Error {}

impl Error {
    pub(crate) fn io(error: io::Error) -> Self {
        Self {
            inner: Box::new(ErrorImpl {
                code: ErrorCode::Io(error),
                line: 0,
                column: 0,
            }),
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Self::io(err)
    }
}

fn make_error(mut msg: String) -> Error {
    let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0));
    Error {
        inner: Box::new(ErrorImpl {
            code: ErrorCode::Message(msg.into_boxed_str()),
            line: line,
            column: column,
        }),
    }
}

fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> {
    let start_of_suffix = match msg.rfind(" at line ") {
        Some(index) => index,
        None => return None,
    };

    // Find start and end of line number.
    let start_of_line = start_of_suffix + " at line ".len();
    let mut end_of_line = start_of_line;
    while starts_with_digit(&msg[end_of_line..]) {
        end_of_line += 1;
    }

    if !msg[end_of_line..].starts_with(" column ") {
        return None;
    }

    // Find start and end of column number.
    let start_of_column = end_of_line + " column ".len();
    let mut end_of_column = start_of_column;
    while starts_with_digit(&msg[end_of_column..]) {
        end_of_column += 1;
    }

    if end_of_column < msg.len() {
        return None;
    }

    // Parse numbers.
    let line = match usize::from_str(&msg[start_of_line..end_of_line]) {
        Ok(line) => line,
        Err(_) => return None,
    };
    let column = match usize::from_str(&msg[start_of_column..end_of_column]) {
        Ok(column) => column,
        Err(_) => return None,
    };

    msg.truncate(start_of_suffix);
    Some((line, column))
}

fn starts_with_digit(slice: &str) -> bool {
    match slice.as_bytes().get(0) {
        None => false,
        Some(&byte) => byte >= b'0' && byte <= b'9',
    }
}

M src/lib.rs => src/lib.rs +4 -1
@@ 1,5 1,8 @@
pub mod ser;
pub mod de;
pub mod error;
pub mod ser;

pub use error::{Error, Result};

pub enum Value {
    Atom(String),

M src/ser.rs => src/ser.rs +391 -0
@@ 0,0 1,391 @@
use std::io::{self, Write};

use serde::ser;

use crate::{Error, Result};

pub fn to_string<T>(_value: &T) -> Result<String>
where
    T: ser::Serialize + ?Sized,
{
    todo!()
}

pub struct Serializer<W> {
    writer: W,
}

impl<W: Write> Serializer<W> {
    pub fn new(writer: W) -> Self {
        Self { writer }
    }
}

impl<W: Write> ser::Serializer for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Self;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Self;

    fn serialize_bool(self, v: bool) -> Result<()> {
        if v {
            Ok(self.writer.write_all(b"#t")?)
        } else {
            Ok(self.writer.write_all(b"#f")?)
        }
    }

    fn serialize_i8(self, v: i8) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_i16(self, v: i16) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_i32(self, v: i32) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_i64(self, v: i64) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_u16(self, v: u16) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_u32(self, v: u32) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_u64(self, v: u64) -> Result<()> {
        itoa::write(self.writer, v)?;
        Ok(())
    }

    fn serialize_f32(
        self,
        _: f32,
    ) -> Result<()>
        todo!()
    }

    fn serialize_f64(
        self,
        _: f64,
    ) -> Result<()> {
        todo!()
    }

    fn serialize_char(
        self,
        _: char,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_str(
        self,
        _: &str,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_bytes(
        self,
        _: &[u8],
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_none(
        self,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_some<T>(
        self,
        _: &T,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    >
    where
        T: serde::ser::Serialize,
    {
        todo!()
    }
    fn serialize_unit(
        self,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_unit_struct(
        self,
        _: &'static str,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_unit_variant(
        self,
        _: &'static str,
        _: u32,
        _: &'static str,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_newtype_struct<T>(
        self,
        _: &'static str,
        _: &T,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    >
    where
        T: serde::ser::Serialize,
    {
        todo!()
    }
    fn serialize_newtype_variant<T>(
        self,
        _: &'static str,
        _: u32,
        _: &'static str,
        _: &T,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::Ok,
        <Self as serde::ser::Serializer>::Error,
    >
    where
        T: serde::ser::Serialize,
    {
        todo!()
    }
    fn serialize_seq(
        self,
        _: std::option::Option<usize>,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeSeq,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_tuple(
        self,
        _: usize,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeTuple,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_tuple_struct(
        self,
        _: &'static str,
        _: usize,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeTupleStruct,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_tuple_variant(
        self,
        _: &'static str,
        _: u32,
        _: &'static str,
        _: usize,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeTupleVariant,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_map(
        self,
        _: std::option::Option<usize>,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeMap,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_struct(
        self,
        _: &'static str,
        _: usize,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeStruct,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
    fn serialize_struct_variant(
        self,
        _: &'static str,
        _: u32,
        _: &'static str,
        _: usize,
    ) -> std::result::Result<
        <Self as serde::ser::Serializer>::SerializeStructVariant,
        <Self as serde::ser::Serializer>::Error,
    > {
        todo!()
    }
}

impl<W: Write> ser::SerializeSeq for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, _: &T) -> Result<()>
    where
        T: serde::ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}

impl<W: Write> ser::SerializeTuple for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, _: &T) -> Result<()>
    where
        T: serde::ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}

impl<W: Write> ser::SerializeTupleStruct for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, _: &T) -> Result<()>
    where
        T: serde::ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}

impl<W: Write> ser::SerializeTupleVariant for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, _: &T) -> Result<()>
    where
        T: serde::ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}

impl<W: Write> ser::SerializeMap for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T>(&mut self, _: &T) -> Result<()>
    where
        T: serde::ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn serialize_value<T>(&mut self, _: &T) -> Result<()>
    where
        T: serde::ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}

impl<W: Write> ser::SerializeStruct for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, _: &'static str, _: &T) -> Result<()>
    where
        T: ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}

impl<W: Write> ser::SerializeStructVariant for &mut Serializer<W> {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, _: &'static str, _: &T) -> Result<()>
    where
        T: ser::Serialize + ?Sized,
    {
        todo!()
    }

    fn end(self) -> Result<()> {
        todo!()
    }
}