Skip to content

Commit

Permalink
Propageted rorm-db change into the Decoder trait
Browse files Browse the repository at this point in the history
  • Loading branch information
gammelalf committed Sep 17, 2024
1 parent bbba768 commit f7646f8
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 63 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Since 0.6.3
- implemented `Condition` on `Arc<dyn Condition>`
- added shorter syntax for `Model::F.field`: `Model.field`
- implemented condition collections for `Option<impl Condition>`
- changed error type returned by Decoder methods

- relaxed / fixed lifetimes
- improved error spans in or! and and!
Expand Down
2 changes: 1 addition & 1 deletion rorm-cli
Submodule rorm-cli updated 1 files
+1 −1 src/migrate/mod.rs
2 changes: 1 addition & 1 deletion rorm-db
4 changes: 2 additions & 2 deletions rorm-macro/src/generate/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ pub fn partially_generate_patch<'a>(
impl ::rorm::crud::decoder::Decoder for #decoder {
type Result = #patch;

fn by_name(&self, row: &::rorm::db::Row) -> Result<Self::Result, ::rorm::Error> {
fn by_name<'index>(&'index self, row: &'_ ::rorm::db::Row) -> Result<Self::Result, ::rorm::db::row::RowError<'index>> {
Ok(#patch {#(
#fields_2: self.#fields_2.by_name(row)?,
)*})
}

fn by_index(&self, row: &::rorm::db::Row) -> Result<Self::Result, ::rorm::Error> {
fn by_index<'index>(&'index self, row: &'_ ::rorm::db::Row) -> Result<Self::Result, ::rorm::db::row::RowError<'index>> {
Ok(#patch {#(
#fields_3: self.#fields_3.by_index(row)?,
)*})
Expand Down
20 changes: 10 additions & 10 deletions src/crud/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use std::marker::PhantomData;

use rorm_db::row::DecodeOwned;
use rorm_db::{Error, Row};
use rorm_db::row::{DecodeOwned, RowError};
use rorm_db::Row;

/// Something which decodes a [value](Self::Result) from a [`&Row`](rorm_db::Row)
///
Expand All @@ -23,10 +23,10 @@ pub trait Decoder {
type Result;

/// Decode a value from a row using select aliases to access the columns
fn by_name(&self, row: &Row) -> Result<Self::Result, Error>;
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>>;

/// Decode a value from a row using indexes to access the columns
fn by_index(&self, row: &Row) -> Result<Self::Result, Error>;
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>>;
}

/// A [`Decoder`] which directly decodes a [`T: DecodedOwned`](DecodeOwned)
Expand All @@ -41,11 +41,11 @@ where
{
type Result = T;

fn by_name(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
row.get(self.column.as_str())
}

fn by_index(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
row.get(self.index)
}
}
Expand All @@ -60,11 +60,11 @@ where
{
type Result = T;

fn by_name(&self, _row: &Row) -> Result<T, Error> {
fn by_name<'index>(&'index self, _row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
Ok(Default::default())
}

fn by_index(&self, _row: &Row) -> Result<T, Error> {
fn by_index<'index>(&'index self, _row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
Ok(Default::default())
}
}
Expand All @@ -76,13 +76,13 @@ macro_rules! decoder {
$S::Result,
)+);

fn by_name(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
Ok(($(
self.$index.by_name(row)?,
)+))
}

fn by_index(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
Ok(($(
self.$index.by_index(row)?,
)+))
Expand Down
6 changes: 4 additions & 2 deletions src/crud/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ where
&returning,
)
.await?;
decoder.by_index(&row)
Ok(decoder.by_index(&row)?)
}

/// Insert a bulk of patches into the db
Expand Down Expand Up @@ -177,7 +177,9 @@ where
&returning,
)
.await?;
rows.iter().map(|row| decoder.by_index(row)).collect()
rows.iter()
.map(|row| decoder.by_index(row).map_err(Into::into))
.collect()
}
}

Expand Down
18 changes: 4 additions & 14 deletions src/crud/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,7 @@ where
)
.await?
.into_iter()
.map(|x| {
decoder
.by_name(&x)
.map_err(|_| Error::DecodeError("Could not decode row".to_string()))
})
.map(|x| decoder.by_name(&x).map_err(Into::into))
.collect::<Result<Vec<_>, _>>()
}

Expand Down Expand Up @@ -241,9 +237,7 @@ where
self.lim_off.into_option(),
)
.await?;
decoder
.by_name(&row)
.map_err(|_| Error::DecodeError("Could not decode row".to_string()))
decoder.by_name(&row).map_err(Into::into)
}

/// Try to retrieve and decode a matching row
Expand All @@ -268,11 +262,7 @@ where
.await?;
match row {
None => Ok(None),
Some(row) => {
Ok(Some(decoder.by_name(&row).map_err(|_| {
Error::DecodeError("Could not decode row".to_string())
})?))
}
Some(row) => Ok(Some(decoder.by_name(&row)?)),
}
}
}
Expand Down Expand Up @@ -468,7 +458,7 @@ mod query_stream {
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let mut projection = self.project();
projection.stream.as_mut().poll_next(cx).map(|option| {
option.map(|result| result.and_then(|row| projection.decoder.by_name(&row)))
option.map(|result| result.and_then(|row| Ok(projection.decoder.by_name(&row)?)))
})
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/fields/types/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use crate::fields::utils::check::shared_linter_check;
use crate::fields::utils::get_annotations::{forward_annotations, set_null_annotations};
use crate::fields::utils::get_names::single_column_name;
use crate::new_converting_decoder;
use crate::Error::DecodeError;

/// Stores data by serializing it to json.
///
Expand Down Expand Up @@ -47,7 +46,7 @@ new_converting_decoder!(
|value: Vec<u8>| -> Json<T> {
serde_json::from_slice(&value)
.map(Json)
.map_err(|err| DecodeError(format!("Couldn't decoder json: {err}")))
.map_err(|err| format!("Couldn't decoder json: {err}"))
}
);
impl<T: Serialize + DeserializeOwned + 'static> FieldType for Json<T> {
Expand Down Expand Up @@ -83,7 +82,7 @@ new_converting_decoder!(
.map(|value| {
serde_json::from_slice(&value)
.map(Json)
.map_err(|err| DecodeError(format!("Couldn't decoder json: {err}")))
.map_err(|err| format!("Couldn't decoder json: {err}"))
})
.transpose()
}
Expand Down
52 changes: 37 additions & 15 deletions src/fields/types/max_str.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use std::borrow::Cow;
use std::fmt;
use std::marker::PhantomData;
use std::ops::Deref;

use rorm_db::row::RowError;
use rorm_db::sql::value::NullType;
use rorm_db::{Error, Row};
use rorm_db::Row;
use serde::de::Unexpected;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

Expand Down Expand Up @@ -113,6 +115,14 @@ pub struct MaxLenError<Str = String> {
pub got: usize,
}

impl<Str: Deref<Target = str>> fmt::Display for MaxLenError<Str> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "string is longer than {max}", max = self.max)
}
}

impl<Str: fmt::Debug + Deref<Target = str>> std::error::Error for MaxLenError<Str> {}

impl<const MAX_LEN: usize, Impl, Str> Deref for MaxStr<MAX_LEN, Impl, Str>
where
Str: Deref<Target = str>,
Expand Down Expand Up @@ -187,14 +197,22 @@ where
{
type Result = MaxStr<MAX_LEN, Impl, String>;

fn by_name(&self, row: &Row) -> Result<Self::Result, Error> {
MaxStr::<MAX_LEN, Impl, String>::new(row.get(self.column.as_str())?)
.map_err(|_| Error::DecodeError(format!("string is longer than {MAX_LEN}")))
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
MaxStr::<MAX_LEN, Impl, String>::new(row.get(self.column.as_str())?).map_err(|error| {
RowError::Decode {
index: self.column.as_str().into(),
source: error.into(),
}
})
}

fn by_index(&self, row: &Row) -> Result<Self::Result, Error> {
MaxStr::<MAX_LEN, Impl, String>::new(row.get(self.index)?)
.map_err(|_| Error::DecodeError(format!("string is longer than {MAX_LEN}")))
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
MaxStr::<MAX_LEN, Impl, String>::new(row.get(self.index)?).map_err(|error| {
RowError::Decode {
index: self.index.into(),
source: error.into(),
}
})
}
}

Expand Down Expand Up @@ -258,20 +276,24 @@ where
{
type Result = Option<MaxStr<MAX_LEN, Impl, String>>;

fn by_name(&self, row: &Row) -> Result<Self::Result, Error> {
row.get::<Option<String>, _>(self.column.as_str())?
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
row.get::<Option<String>>(self.column.as_str())?
.map(|string| {
MaxStr::<MAX_LEN, Impl, String>::new(string)
.map_err(|_| Error::DecodeError(format!("string is longer than {MAX_LEN}")))
MaxStr::<MAX_LEN, Impl, String>::new(string).map_err(|error| RowError::Decode {
index: self.column.as_str().into(),
source: error.into(),
})
})
.transpose()
}

fn by_index(&self, row: &Row) -> Result<Self::Result, Error> {
row.get::<Option<String>, _>(self.index)?
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
row.get::<Option<String>>(self.index)?
.map(|string| {
MaxStr::<MAX_LEN, Impl, String>::new(string)
.map_err(|_| Error::DecodeError(format!("string is longer than {MAX_LEN}")))
MaxStr::<MAX_LEN, Impl, String>::new(string).map_err(|error| RowError::Decode {
index: self.column.as_str().into(),
source: error.into(),
})
})
.transpose()
}
Expand Down
5 changes: 2 additions & 3 deletions src/fields/types/msgpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::borrow::Cow;
use std::ops::{Deref, DerefMut};

use rorm_db::sql::value::NullType;
use rorm_db::Error::DecodeError;
use serde::de::DeserializeOwned;
use serde::Serialize;

Expand Down Expand Up @@ -47,7 +46,7 @@ new_converting_decoder!(
|value: Vec<u8>| -> MsgPack<T> {
rmp_serde::from_slice(&value)
.map(MsgPack)
.map_err(|err| DecodeError(format!("Couldn't decode msg pack: {err}")))
.map_err(|err| format!("Couldn't decode msg pack: {err}"))
}
);
impl<T: Serialize + DeserializeOwned + 'static> FieldType for MsgPack<T> {
Expand Down Expand Up @@ -81,7 +80,7 @@ new_converting_decoder!(
.map(|value| {
rmp_serde::from_slice(&value)
.map(MsgPack)
.map_err(|err| DecodeError(format!("Couldn't decode msg pack: {err}")))
.map_err(|err| format!("Couldn't decode msg pack: {err}"))
})
.transpose()
}
Expand Down
6 changes: 3 additions & 3 deletions src/fields/types/url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::fields::traits::{Array, FieldColumns, FieldType};
use crate::fields::utils::check::string_check;
use crate::fields::utils::get_annotations::{forward_annotations, set_null_annotations};
use crate::fields::utils::get_names::single_column_name;
use crate::{impl_FieldEq, new_converting_decoder, Error};
use crate::{impl_FieldEq, new_converting_decoder};

impl_FieldEq!(impl<'rhs> FieldEq<'rhs, &'rhs Url> for Url {|url: &'rhs Url| Value::String(Cow::Borrowed(url.as_str()))});
impl_FieldEq!(impl<'rhs> FieldEq<'rhs, Url> for Url {|url: Url| Value::String(Cow::Owned(url.into()))});
Expand Down Expand Up @@ -38,7 +38,7 @@ impl FieldType for Url {
new_converting_decoder!(
pub UrlDecoder,
|value: String| -> Url {
Url::parse(&value).map_err(|err| Error::DecodeError(format!("Couldn't parse url: {err}")))
Url::parse(&value).map_err(|err| format!("Couldn't parse url: {err}"))
}
);

Expand Down Expand Up @@ -69,6 +69,6 @@ impl FieldType for Option<Url> {
new_converting_decoder!(
pub OptionUrlDecoder,
|value: Option<String>| -> Option<Url> {
value.map(|string| Url::parse(&string)).transpose().map_err(|err| Error::DecodeError(format!("Couldn't parse url: {err}")))
value.map(|string| Url::parse(&string)).transpose().map_err(|err| format!("Couldn't parse url: {err}"))
}
);
16 changes: 12 additions & 4 deletions src/internal/field/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,22 @@ macro_rules! new_converting_decoder {
{
type Result = $result;

fn by_name(&self, row: &$crate::Row) -> Result<Self::Result, $crate::Error> {
fn by_name<'index>(&'index self, row: &'_ $crate::Row) -> Result<Self::Result, $crate::db::row::RowError<'index>> {
let $convert_arg: $primitive = row.get(self.column.as_str())?;
$convert_block
let convert_result = $convert_block;
convert_result.map_err(|error| $crate::db::row::RowError::Decode {
index: self.column.as_str().into(),
source: error.into(),
})
}

fn by_index(&self, row: &$crate::Row) -> Result<Self::Result, $crate::Error> {
fn by_index<'index>(&'index self, row: &'_ $crate::Row) -> Result<Self::Result, $crate::db::row::RowError<'index>> {
let $convert_arg: $primitive = row.get(self.index)?;
$convert_block
let convert_result = $convert_block;
convert_result.map_err(|error| $crate::db::row::RowError::Decode {
index: self.index.into(),
source: error.into(),
})
}
}
impl$(<$($generic),*>)? $crate::internal::field::decoder::FieldDecoder for $decoder$(<$($generic),+>)?
Expand Down
11 changes: 6 additions & 5 deletions src/internal/field/foreign_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

use std::marker::PhantomData;

use rorm_db::row::RowError;
use rorm_db::sql::value::NullType;
use rorm_db::{Error, Row};
use rorm_db::Row;

use crate::conditions::Value;
use crate::const_fn;
Expand Down Expand Up @@ -171,11 +172,11 @@ pub struct ForeignModelByFieldDecoder<FF: SingleColumnField>(<FF::Type as FieldT
impl<FF: SingleColumnField> Decoder for ForeignModelByFieldDecoder<FF> {
type Result = ForeignModelByField<FF>;

fn by_name(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
self.0.by_name(row).map(ForeignModelByField::Key)
}

fn by_index(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
self.0.by_index(row).map(ForeignModelByField::Key)
}
}
Expand Down Expand Up @@ -204,13 +205,13 @@ where
{
type Result = Option<ForeignModelByField<FF>>;

fn by_name(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_name<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
self.0
.by_name(row)
.map(|option| option.map(ForeignModelByField::Key))
}

fn by_index(&self, row: &Row) -> Result<Self::Result, Error> {
fn by_index<'index>(&'index self, row: &'_ Row) -> Result<Self::Result, RowError<'index>> {
self.0
.by_index(row)
.map(|option| option.map(ForeignModelByField::Key))
Expand Down

0 comments on commit f7646f8

Please sign in to comment.