Created
September 8, 2021 10:48
-
-
Save ColinTimBarndt/28857d3f955dfd1fadea01b6fe0fe450 to your computer and use it in GitHub Desktop.
Diesel wrapper for Smallstring
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mod smallstring { | |
use std::{ | |
fmt, | |
ops::{Deref, DerefMut}, | |
}; | |
use diesel::{backend::Backend, types::FromSql}; | |
use serde::{Deserialize, Serialize}; | |
use smallstr::SmallString as ExtSmallString; | |
pub struct SmallString<A>(ExtSmallString<A>) | |
where | |
A: smallvec::Array<Item = u8>; | |
impl<A> SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
pub fn new() -> Self { | |
Self(ExtSmallString::new()) | |
} | |
pub fn allocate(n: usize) -> Self { | |
Self(ExtSmallString::with_capacity(n)) | |
} | |
} | |
impl<A, ST, DB> FromSql<ST, DB> for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
DB: Backend, | |
*const str: FromSql<ST, DB>, | |
{ | |
fn from_sql(bytes: Option<&DB::RawValue>) -> diesel::deserialize::Result<Self> { | |
let str_ptr = <*const str as FromSql<ST, DB>>::from_sql(bytes)?; | |
// We know that the pointer impl will never return null | |
let string = unsafe { &*str_ptr }; | |
if string.len() <= A::size() { | |
Ok(SmallString(ExtSmallString::from_str(string))) | |
} else { | |
Err("String size exceeds bounds".into()) | |
} | |
} | |
} | |
impl<A> Deref for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
type Target = ExtSmallString<A>; | |
fn deref(&self) -> &Self::Target { | |
&self.0 | |
} | |
} | |
impl<A> DerefMut for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
fn deref_mut(&mut self) -> &mut Self::Target { | |
&mut self.0 | |
} | |
} | |
impl<A> AsRef<ExtSmallString<A>> for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
fn as_ref(&self) -> &ExtSmallString<A> { | |
&self.0 | |
} | |
} | |
impl<A> AsMut<ExtSmallString<A>> for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
fn as_mut(&mut self) -> &mut ExtSmallString<A> { | |
&mut self.0 | |
} | |
} | |
impl<A> From<ExtSmallString<A>> for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
fn from(ext: ExtSmallString<A>) -> Self { | |
Self(ext) | |
} | |
} | |
impl<A> fmt::Debug for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
#[inline] | |
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
self.0.fmt(f) | |
} | |
} | |
impl<A> fmt::Display for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
#[inline] | |
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
self.0.fmt(f) | |
} | |
} | |
impl<A> Serialize for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | |
where | |
S: serde::Serializer, | |
{ | |
self.0.serialize(serializer) | |
} | |
} | |
impl<'de, A> Deserialize<'de> for SmallString<A> | |
where | |
A: smallvec::Array<Item = u8>, | |
{ | |
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
Ok(Self(ExtSmallString::deserialize(deserializer)?)) | |
} | |
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> | |
where | |
D: serde::Deserializer<'de>, | |
{ | |
ExtSmallString::deserialize_in_place(deserializer, &mut place.0)?; | |
Ok(()) | |
} | |
} | |
mod foreign_impls { | |
#[allow(dead_code)] | |
use super::*; | |
#[derive(FromSqlRow)] | |
#[diesel(foreign_derive)] | |
//#[sql_type = "Text"] | |
struct SmallStringProxy<A>(SmallString<A>) | |
where | |
A: smallvec::Array<Item = u8>; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment