now using serde CBOR

legacy
Avril 4 years ago
parent f8adf9721a
commit 04f35d36d6
Signed by: flanchan
GPG Key ID: 284488987C31F630

46
Cargo.lock generated

@ -64,6 +64,7 @@ checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
dependencies = [
"num-integer",
"num-traits",
"serde",
"time",
]
@ -75,11 +76,13 @@ checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]]
name = "cryptohelpers"
version = "0.1.1"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8689d930e1c3d1cbd99014c9f7bf1a1197db8e0665ff134517b86c78233ef4fb"
checksum = "3aea2aded66cedf86364894060626fd5837b10b81d8a9592bc0bcde7a5a3af3d"
dependencies = [
"libc",
"serde",
"serde_derive",
"sha2",
"tokio",
]
@ -142,6 +145,12 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "half"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177"
[[package]]
name = "hermit-abi"
version = "0.1.15"
@ -414,6 +423,36 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_cbor"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
dependencies = [
"half",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "sha2"
version = "0.9.1"
@ -531,6 +570,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
dependencies = [
"rand",
"serde",
]
[[package]]
@ -606,6 +646,8 @@ dependencies = [
"libc",
"once_cell",
"rustc_version",
"serde",
"serde_cbor",
"tokio",
"uuid",
]

@ -9,12 +9,14 @@ edition = "2018"
[dependencies]
tokio = {version = "0.2", features=["full"]}
async-trait = "0.1.40"
chrono = "0.4.15"
uuid = {version = "0.8", features=["v4"]}
chrono = {version = "0.4.15", features=["serde"]}
uuid = {version = "0.8", features=["v4", "serde"]}
once_cell = "1.4.1"
crypto = {package= "cryptohelpers", version = "0.1", features= ["async", "sha256"]}
crypto = {version = "1.1.1", package= "cryptohelpers", features= ["serialise", "async", "sha256"]}
libc = "0.2.76"
byteorder = "1.3.4"
serde_cbor = "0.11.1"
serde = {version = "1.0.115", features= ["derive"]}
[build-dependencies]
rustc_version = "0.2"

@ -5,13 +5,13 @@ use std::{
use libc::c_void;
pub unsafe fn refer<'a, T>(src: &'a T) -> &'a [u8]
where T: ?Sized
where T: ?Sized
{
std::slice::from_raw_parts(src as *const T as *const u8, std::mem::size_of_val(src))
}
pub unsafe fn refer_mut<'a, T>(src: &'a mut T) -> &'a mut [u8]
where T: ?Sized
where T: ?Sized
{
std::slice::from_raw_parts_mut(src as *mut T as *mut u8, std::mem::size_of_val(src))
}
@ -27,58 +27,60 @@ pub unsafe fn derefer_mut<'a, T>(src: &'a mut [u8]) -> &'a mut T
assert!(src.len() >= std::mem::size_of::<T>());
&mut *(&mut src[0] as *mut u8 as *mut T)
}
/// Represents a type that can be converted from bytes to itself
pub trait FromBytes: Sized
{
mod old {
use super::*;
/// Represents a type that can be converted from bytes to itself
pub trait FromBytes: Sized
{
type Error;
fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self,Self::Error>;
}
}
/// Represents a type that can be converted into bytes
pub trait IntoBytes:Sized
{
/// Represents a type that can be converted into bytes
pub trait IntoBytes:Sized
{
fn into_bytes(self) -> Box<[u8]>;
}
}
impl<T: Into<Box<[u8]>>> IntoBytes for T
{
impl<T: Into<Box<[u8]>>> IntoBytes for T
{
#[inline] fn into_bytes(self) -> Box<[u8]>
{
self.into()
}
}
}
impl FromBytes for Vec<u8>
{
impl FromBytes for Vec<u8>
{
type Error = !;
#[inline] fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self,Self::Error>
{
Ok(Vec::from(bytes.as_ref()))
}
}
impl FromBytes for Box<[u8]>
{
}
impl FromBytes for Box<[u8]>
{
type Error = !;
#[inline] fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self,Self::Error>
{
Ok(Vec::from(bytes.as_ref()).into_boxed_slice())
}
}
}
/// The error used when a `FromBytes` conversion fails because the buffer was not the correct size
#[derive(Debug)]
pub struct SizeError;
impl error::Error for SizeError{}
impl fmt::Display for SizeError
{
/// The error used when a `FromBytes` conversion fails because the buffer was not the correct size
#[derive(Debug)]
pub struct SizeError;
impl error::Error for SizeError{}
impl fmt::Display for SizeError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f,"buffer was not the correct size")
}
}
}
}
/// Copy slice of bytes only
///
/// # Notes

@ -1,4 +1,7 @@
use super::*;
use std::{
borrow::Cow,
};
//TODO: Use tokio Watcher instead, to allow hotreloading?
use once_cell::sync::OnceCell;
@ -24,7 +27,7 @@ pub fn get() -> &'static Config
pub struct Config
{
/// Name for nanashi
pub anon_name: String,
pub anon_name: Cow<'static, str>,
}
impl Default for Config
@ -33,7 +36,7 @@ impl Default for Config
fn default() -> Self
{
Self {
anon_name: "Nanashi",
anon_name: Cow::Borrowed("Nanashi"),
}
}
}

@ -7,31 +7,9 @@ use uuid::Uuid;
/// A globally unique post identifier.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[derive(Serialize, Deserialize)]
pub struct PostID(Uuid);
impl bytes::IntoBytes for PostID
{
fn into_bytes(self) -> Box<[u8]>
{
Box::from(*self.0.as_bytes())
}
}
impl bytes::FromBytes for PostID
{
type Error = bytes::SizeError;
fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self,Self::Error> {
let bytes = bytes.as_ref();
if bytes.len() < 16 {
Err(bytes::SizeError)
} else {
let by = [0u8; 16];
assert_eq!(bytes::copy_slice(&mut by[..], bytes), 16);
Ok(Self(Uuid::from_bytes(by)))
}
}
}
impl PostID
{
/// Generate a new `PostID`.
@ -51,6 +29,7 @@ impl fmt::Display for PostID
/// A user's data, if set.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
#[derive(Serialize, Deserialize)]
pub struct User
{
pub name: Option<String>,

@ -4,12 +4,8 @@
#![allow(dead_code)]
use async_trait::async_trait;
use self::{
bytes::{
FromBytes as _,
IntoBytes as _,
},
use serde::{
Serialize, Deserialize,
};
mod bytes;

@ -12,63 +12,15 @@ use chrono::prelude::*;
///
/// Usually in UTC, pls keep it in Utc...
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PostTimestamp<T = Utc>
where T: TimeZone,
#[derive(Serialize, Deserialize)]
pub struct PostTimestamp
{
pub opened: DateTime<T>,
pub closed: Option<DateTime<T>>,
pub last_edit: DateTime<T>,
pub opened: DateTime<Utc>,
pub closed: Option<DateTime<Utc>>,
pub last_edit: DateTime<Utc>,
}
impl<T> bytes::IntoBytes for PostTimestamp<T>
where T: TimeZone,
{
fn into_bytes(self) -> Box<[u8]> {
const ESIZE: usize = std::mem::size_of::<i64>();
let mut output =[0u8; ESIZE * 3];
use byteorder::{
LittleEndian,
WriteBytesExt,
};
//FUCK this. why is ther eno from_timestamp_nanos()!??? wtf is the point of the nanos versions then?????? fuck
output[..ESIZE] .as_mut().write_i64::<LittleEndian>(self.opened.timestamp()).unwrap();
output[ESIZE..ESIZE*2] .as_mut().write_i64::<LittleEndian>(self.closed.map(|x| x.timestamp()).unwrap_or(i64::MIN)).unwrap();
output[ESIZE*2..ESIZE*3].as_mut().write_i64::<LittleEndian>(self.last_edit.timestamp()).unwrap();
output.into()
}
}
impl bytes::FromBytes for PostTimestamp
{
type Error = bytes::SizeError;
fn from_bytes<U: AsRef<[u8]>>(bytes: U) -> Result<Self,Self::Error> {
const ESIZE: usize = std::mem::size_of::<i64>();
let bytes=bytes.as_ref();
if bytes.len() < ESIZE * 3 {
return Err(bytes::SizeError);
}
use byteorder::{
LittleEndian,
ReadBytesExt,
};
let opened = bytes.read_i64::<LittleEndian>().unwrap();
let closed = match bytes[ESIZE..].as_ref().read_i64::<LittleEndian>().unwrap() {
i64::MIN => None,
x => Some(x),
};
let last_edit = bytes[ESIZE*2..].as_ref().read_i64::<LittleEndian>().unwrap();
Ok(Self{
opened: DateTime::from_utc(NaiveDateTime::from_timestamp(opened, 0), Utc),
closed: closed.map(|closed| DateTime::from_utc(NaiveDateTime::from_timestamp(closed, 0), Utc)),
last_edit: DateTime::from_utc(NaiveDateTime::from_timestamp(last_edit, 0), Utc),
})
}
}
impl<Tz: TimeZone> Hash for PostTimestamp<Tz> {
impl Hash for PostTimestamp {
fn hash<H: Hasher>(&self, state: &mut H) {
self.opened.hash(state);
self.closed.hash(state);
@ -76,9 +28,7 @@ impl<Tz: TimeZone> Hash for PostTimestamp<Tz> {
}
}
impl<T> fmt::Display for PostTimestamp<T>
where T: TimeZone,
T::Offset: fmt::Display
impl fmt::Display for PostTimestamp
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
@ -94,7 +44,7 @@ where T: TimeZone,
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
/// A closed and finished post. The inverse of `Imouto`.
pub struct Static
{
@ -122,26 +72,12 @@ impl Suspendable for Static
async fn suspend<S: SuspendStream +Send+Sync + ?Sized>(self, into: &mut S) -> Result<(), suspend::Error>
{
let mut output = suspend::Object::new();
output.insert_value("id", self.id);
output.insert_bool("Some(user-name)", self.user.name.is_some());
output.insert_string("user-name", self.user.name.unwrap_or_default());
output.insert_bool("Some(user-email)", self.user.email.is_some());
output.insert_string("user-email", self.user.email.unwrap_or_default());
//TODO: Tripcode
output.insert_bool("Some(title)", self.title.is_some());
output.insert_string("title", self.title.unwrap_or_default());
output.insert_string("body", self.karada);
output.insert_value("timestamp", self.timestamp);
output.insert_bytes("hash", self.hash);
output.insert("post-static", self);
into.set_object(output).await
}
async fn load<S: SuspendStream +Send+Sync+ ?Sized>(from: &mut S) -> Result<Self, suspend::Error>
{
fuck
todo!() //ehhhh... this is so dumb...
let mut input = from.get_object().await?.ok_or(suspend::Error::BadObject)?;
input.try_get("post-static").ok_or(suspend::Error::BadObject)
}
}

@ -74,7 +74,7 @@ pub struct Karada
/// Handles working on `Karada` instances.
pub struct Kokoro
{
...//TODO
// ...//TODO
}
/// An open, as yet unfinied post

@ -24,10 +24,6 @@ use tokio::{
AsyncWrite,
},
};
use bytes::{
IntoBytes,
FromBytes,
};
/// Represents an opaque bytes stream of serialised data to insert into `SuspendStream`.
#[derive(Debug, Clone, PartialEq, Eq)]
@ -56,6 +52,7 @@ where I: IntoIterator<Item = T>,
impl Object
{
/// Create a new empty `Object`.
#[inline] pub fn new() -> Self
{
@ -74,42 +71,43 @@ impl Object
true
}
/// Insert a boolean
pub fn insert_bool(&mut self, name: impl Into<Cow<'static, str>>, value: bool)
/// Try to get a value of type `T` from `name`.
pub fn get<'a, T>(&'a mut self, name: impl Borrow<str>) -> Option<T>
where T: Deserialize<'a>
{
self.insert_bytes(name, if value {&[1]} else {&[0]})
if let Some(bytes) = self.get_bytes(name) {
serde_cbor::from_slice(&bytes[..]).expect("Failed to deserialize CBOR value")
} else {
None
}
/// Get a boolean
pub fn get_bool(&self, name: impl Borrow<str>) -> Option<bool>
{
self.get_bytes(name).map(|x| if x[0]==0 {false} else {true})
}
/// Insert a UTF-8 string
pub fn insert_string(&mut self, name: impl Into<Cow<'static, str>>, stri: impl AsRef<str>)
{
self.insert_bytes(name, stri.as_ref().as_bytes())
}
/// Try to get a UTF-8 string, returning `None` if either the name was not present, or the string was not formatted correctly
pub fn try_get_string(&self, name: impl Borrow<str>) -> Option<&str>
/// Try to get a value of type `T` from `name`.
pub fn try_get<'a, T>(&'a mut self, name: impl Borrow<str>) -> Option<T>
where T: Deserialize<'a>
{
if let Some(bytes) = self.get_bytes(name) {
std::str::from_utf8(bytes).ok()
serde_cbor::from_slice(&bytes[..]).ok()
} else {
None
}
}
/// Try to get a UTF-8 string, returning `None` if the name was not present
///
/// # Panics
/// If the present string was not valid UTF-8
pub fn get_string(&self, name: impl Borrow<str>) -> Option<&str>
/// Serialize and insert `value` into the stream with `name`.
pub fn insert<T>(&mut self, name: impl Into<Cow<'static, str>>, value: T)
where T: Serialize
{
if let Some(bytes) = self.get_bytes(name) {
Some(std::str::from_utf8(bytes).expect("String contained invalid UTF-8"))
} else {
None
let len = self.data.len();
match serde_cbor::to_writer(&mut self.data, &value) {
Ok(()) => {
let nlen = self.data.len();
self.data_instances.insert(name.into(), len..nlen).unwrap_none();
},
Err(err) => {
self.data.resize(len, 0); //Roll back result
panic!("Failed inserting CBOR object: {}", err) //TODO: Return Err instead of panic
},
}
}
@ -132,25 +130,6 @@ impl Object
self.insert_bytes(name, bytes::refer(value))
}
/// Convert a value to bytes and insert it into this object
pub fn insert_value<T: IntoBytes, U>(&mut self, name: U, value: T)
where U: Into<Cow<'static, str>>
{
self.insert_bytes(name, value.into_bytes())
}
/// Try to get a value from the bytes specified by name
pub fn get_value<T>(&self, name: impl Borrow<str>) -> Result<Option<T>, T::Error>
where T: FromBytes
{
if let Some(range) = self.data_instances.get(name.borrow()) {
Ok(Some(T::from_bytes(&self.data[range.clone()])?))
} else {
Ok(None)
}
}
/// Try to get the bytes specified by name
pub fn get_bytes(&self, name: impl Borrow<str>) -> Option<&[u8]>
{

@ -4,9 +4,10 @@ use super::*;
///TODO: A kana-hash tripcode
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum Tripcode
#[derive(Serialize, Deserialize)]
pub struct Tripcode;/*
{
Secure(i32),
Normal(i32),
Special(&'static str),
}
}*/

Loading…
Cancel
Save