Add serde serializer for record values

Signed-off-by: trivernis <trivernis@protonmail.com>
integration-not-installation
trivernis 2 years ago
parent 6c21d3164a
commit 1b617577e2
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,4 +1,5 @@
pub mod executor; pub mod executor;
pub mod loader; pub mod loader;
pub mod record; pub mod record;
pub mod record_serializer;
pub mod script; pub mod script;

@ -10,6 +10,7 @@ pub enum RecordValue {
Int(i64), Int(i64),
Float(f64), Float(f64),
String(String), String(String),
Bytes(Vec<u8>),
Boolean(bool), Boolean(bool),
Null, Null,
Map(Vec<(RecordValue, RecordValue)>), Map(Vec<(RecordValue, RecordValue)>),
@ -32,6 +33,7 @@ impl RecordValue {
RecordValue::List(l) => { RecordValue::List(l) => {
Expr::List(l.into_iter().map(RecordValue::into_expression).collect()) Expr::List(l.into_iter().map(RecordValue::into_expression).collect())
} }
RecordValue::Bytes(b) => Expr::Binary(b),
} }
} }
@ -69,6 +71,7 @@ impl RecordValue {
}; };
Type::List(Box::new(list_type)) Type::List(Box::new(list_type))
} }
RecordValue::Bytes(_) => Type::Binary,
} }
} }
} }
@ -83,6 +86,7 @@ impl ToString for RecordValue {
RecordValue::Null => String::new(), RecordValue::Null => String::new(),
RecordValue::Map(_) => String::new(), RecordValue::Map(_) => String::new(),
RecordValue::List(_) => String::new(), RecordValue::List(_) => String::new(),
RecordValue::Bytes(_) => String::new(),
} }
} }
} }
@ -145,3 +149,9 @@ impl<T: Into<RecordValue>> From<Vec<T>> for RecordValue {
Self::List(list) Self::List(list)
} }
} }
impl From<Vec<u8>> for RecordValue {
fn from(b: Vec<u8>) -> Self {
Self::Bytes(b)
}
}

@ -0,0 +1,452 @@
use std::{collections::HashMap, mem};
use thiserror::Error;
use super::record::RecordValue;
#[derive(Default)]
pub struct RecordSerializer {
list_serializer: Option<RecordListSerializer>,
map_serializer: Option<RecordMapSerializer>,
}
pub struct RecordListSerializer {
serializer: Option<Box<RecordSerializer>>,
entries: Vec<RecordValue>,
}
pub struct RecordMapSerializer {
serializer: Option<Box<RecordSerializer>>,
last_key: Option<RecordValue>,
entries: Vec<(RecordValue, RecordValue)>,
}
impl RecordSerializer {
pub fn list_serializer<'a>(&'a mut self, cap: Option<usize>) -> &'a mut RecordListSerializer {
if self.list_serializer.is_none() {
self.list_serializer = Some(RecordListSerializer::with_capacity_opt(cap));
}
self.list_serializer.as_mut().unwrap()
}
pub fn map_serializer(&mut self, cap: Option<usize>) -> &mut RecordMapSerializer {
if self.map_serializer.is_none() {
self.map_serializer = Some(RecordMapSerializer::with_capacity_opt(cap));
}
self.map_serializer.as_mut().unwrap()
}
}
impl RecordListSerializer {
pub fn new() -> Self {
Self {
entries: Vec::new(),
serializer: None,
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
entries: Vec::with_capacity(capacity),
serializer: None,
}
}
pub fn with_capacity_opt(capacity: Option<usize>) -> Self {
match capacity {
Some(cap) => Self::with_capacity(cap),
None => Self::new(),
}
}
pub fn serializer(&mut self) -> &mut RecordSerializer {
if self.serializer.is_none() {
self.serializer = Some(Box::new(RecordSerializer::default()));
}
self.serializer.as_mut().unwrap()
}
}
impl RecordMapSerializer {
pub fn new() -> Self {
Self {
last_key: None,
entries: Vec::new(),
serializer: None,
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
last_key: None,
entries: Vec::with_capacity(capacity),
serializer: None,
}
}
pub fn with_capacity_opt(capacity: Option<usize>) -> Self {
match capacity {
Some(cap) => Self::with_capacity(cap),
None => Self::new(),
}
}
pub fn serializer(&mut self) -> &mut RecordSerializer {
if self.serializer.is_none() {
self.serializer = Some(Box::new(RecordSerializer::default()));
}
self.serializer.as_mut().unwrap()
}
}
#[derive(Error, Debug)]
pub enum RecordSerError {
#[error("{0}")]
Msg(String),
#[error("Encountered map value before map key")]
ValueBeforeKey,
}
impl serde::ser::Error for RecordSerError {
fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
Self::Msg(msg.to_string())
}
}
impl<'a> serde::ser::Serializer for &'a mut RecordSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
type SerializeSeq = &'a mut RecordListSerializer;
type SerializeTuple = &'a mut RecordListSerializer;
type SerializeTupleStruct = &'a mut RecordListSerializer;
type SerializeTupleVariant = &'a mut RecordListSerializer;
type SerializeMap = &'a mut RecordMapSerializer;
type SerializeStruct = &'a mut RecordMapSerializer;
type SerializeStructVariant = &'a mut RecordMapSerializer;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
Ok((v as i64).into())
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
Ok((v as f64).into())
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
Ok(v.to_string().into())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
Ok(v.to_vec().into())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(RecordValue::Null)
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: serde::Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
self.serialize_none()
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T: ?Sized>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde::Serialize,
{
let mut map = HashMap::new();
map.insert(variant.to_string(), value.serialize(self)?);
Ok(map.into())
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Ok(self.list_serializer(len))
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Ok(self.list_serializer(Some(len)))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Ok(self.list_serializer(Some(len)))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Ok(self.list_serializer(Some(len)))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Ok(self.map_serializer(len))
}
fn serialize_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Ok(self.map_serializer(Some(len)))
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Ok(self.map_serializer(Some(len)))
}
}
impl<'a> serde::ser::SerializeTuple for &'a mut RecordListSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = value.serialize(self.serializer())?;
self.entries.push(val);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(mem::take(&mut self.entries).into())
}
}
impl<'a> serde::ser::SerializeSeq for &'a mut RecordListSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = value.serialize(self.serializer())?;
self.entries.push(val);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(mem::take(&mut self.entries).into())
}
}
impl<'a> serde::ser::SerializeTupleStruct for &'a mut RecordListSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = value.serialize(self.serializer())?;
self.entries.push(val);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(mem::take(&mut self.entries).into())
}
}
impl<'a> serde::ser::SerializeTupleVariant for &'a mut RecordListSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = value.serialize(self.serializer())?;
self.entries.push(val);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(mem::take(&mut self.entries).into())
}
}
impl<'a> serde::ser::SerializeMap for &'a mut RecordMapSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = key.serialize(self.serializer())?;
self.last_key = Some(val);
Ok(())
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
if let Some(last_key) = self.last_key.take() {
let val = value.serialize(self.serializer())?;
self.entries.push((last_key, val));
Ok(())
} else {
Err(RecordSerError::ValueBeforeKey)
}
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(RecordValue::Map(mem::take(&mut self.entries)))
}
}
impl<'a> serde::ser::SerializeStruct for &'a mut RecordMapSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = value.serialize(self.serializer())?;
self.entries.push((key.into(), val));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(RecordValue::Map(mem::take(&mut self.entries)))
}
}
impl<'a> serde::ser::SerializeStructVariant for &'a mut RecordMapSerializer {
type Ok = RecordValue;
type Error = RecordSerError;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: serde::Serialize,
{
let val = value.serialize(self.serializer())?;
self.entries.push((key.into(), val));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(RecordValue::Map(mem::take(&mut self.entries)))
}
}

@ -1,10 +1,13 @@
use std::{marker::PhantomData, path::PathBuf}; use std::{marker::PhantomData, path::PathBuf};
use serde::Serialize;
use crate::error::AppResult; use crate::error::AppResult;
use super::{ use super::{
executor::{NuExecutor, VarValue}, executor::{NuExecutor, VarValue},
record::RecordValue, record::RecordValue,
record_serializer::RecordSerializer,
}; };
/// A trait implemented for a given nu script type to /// A trait implemented for a given nu script type to
@ -24,6 +27,17 @@ pub trait ScriptArgs {
fn get_args(self) -> Vec<RecordValue>; fn get_args(self) -> Vec<RecordValue>;
} }
impl<T: Serialize> ScriptArgs for T {
fn get_args(self) -> Vec<RecordValue> {
let mut serializer = RecordSerializer::default();
let val = self.serialize(&mut serializer).unwrap();
match val {
RecordValue::List(entries) => entries,
val => vec![val],
}
}
}
/// A nu script instance that can be executed /// A nu script instance that can be executed
pub struct NuScript<S: Script> { pub struct NuScript<S: Script> {
path: PathBuf, path: PathBuf,

@ -1,11 +1,6 @@
use std::collections::HashMap;
use serde::Serialize; use serde::Serialize;
use crate::scripting::{ use crate::scripting::script::Script;
record::RecordValue,
script::{Script, ScriptArgs},
};
pub struct SetupUsersScript; pub struct SetupUsersScript;
@ -29,22 +24,3 @@ impl Script for SetupUsersScript {
"setup-users.nu" "setup-users.nu"
} }
} }
impl ScriptArgs for UsersConfig {
fn get_args(self) -> Vec<RecordValue> {
let mut user_cfg_map = HashMap::new();
let mut user_cfgs = Vec::new();
for user in self.users {
let mut user_map: HashMap<&'static str, RecordValue> = HashMap::new();
user_map.insert("name", user.name.into());
user_map.insert("password", user.password.into());
user_map.insert("sudoer", user.sudoer.into());
user_map.insert("shell", user.shell.into());
user_cfgs.push(user_map);
}
user_cfg_map.insert("users", user_cfgs);
vec![user_cfg_map.into()]
}
}

Loading…
Cancel
Save