Skip to content

Commit

Permalink
initial Ref<M> impl (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahseguin committed Jan 22, 2023
1 parent 5c1bfed commit 079588d
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 4 deletions.
2 changes: 1 addition & 1 deletion musty-proc-macro/src/model/meta_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl MetaModelDerive {
#(
#attrs
)*
#[derive(Debug, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#vis struct #ident {
#id_attr
#id_vis id: musty::prelude::Id<#ident, #id_type>,
Expand Down
2 changes: 1 addition & 1 deletion musty/examples/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct User {
address: Address,
}

#[derive(Debug, Filter, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, Filter)]
struct Address {
country: String,
labels: Vec<String>,
Expand Down
20 changes: 19 additions & 1 deletion musty/src/filter/value.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{prelude::{Filter, ModelFilter, IdGuard, Id}, Model};
use crate::{prelude::{Filter, ModelFilter, IdGuard, Id}, Model, reference::Ref};

#[derive(Debug, Clone)]
pub enum FilterValue {
Expand Down Expand Up @@ -77,4 +77,22 @@ impl<M: Model, I: IdGuard> From<Id<M, I>> for FilterValue {
fn from(id: Id<M, I>) -> Self {
Self::Id(id.inner.map(|i| i.to_string()))
}
}

impl<M: Model, I: IdGuard> From<&Id<M, I>> for FilterValue {
fn from(id: &Id<M, I>) -> Self {
Self::Id(id.inner.as_ref().map(|i| i.to_string()))
}
}

impl<M: Model> From<Ref<M>> for FilterValue {
fn from(r: Ref<M>) -> Self {
r.take_id().into()
}
}

impl<M: Model> From<&Ref<M>> for FilterValue {
fn from(r: &Ref<M>) -> Self {
r.id().into()
}
}
1 change: 1 addition & 0 deletions musty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod error;
mod id;
mod model;
pub mod filter;
mod reference;

#[cfg(feature = "bson")]
pub use bson;
Expand Down
2 changes: 1 addition & 1 deletion musty/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use async_trait::async_trait;
#[async_trait]
pub trait Model
where
Self: Sized + Send + Sync + Serialize + DeserializeOwned + Unpin,
Self: Sized + Send + Sync + Serialize + DeserializeOwned + Unpin + Clone,
{
type Id: IdGuard;

Expand Down
91 changes: 91 additions & 0 deletions musty/src/reference.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use serde::{Serialize, Deserialize};

use crate::{Model, id::Id, prelude::Backend, Result, context::Context};

#[derive(Clone)]
pub enum Ref<M: Model> {
Id(Id<M, <M as Model>::Id>),
Model(M),
}

impl<M: Model> Ref<M> {
pub async fn get<B, I>(&self, db: &crate::Musty<B>) -> Result<Option<M>>
where
M: Context<<M as Model>::Id, B> + 'static,
I: Into<Id<M, <M as Model>::Id>> + Send + Sync,
B: Backend,
{
match self {
Self::Id(id) => Ok(db.inner.get_model_by_id(id.into()).await?),
Self::Model(model) => Ok(Some(model.clone())),
}
}

pub async fn take<B, I>(self, db: &crate::Musty<B>) -> Result<Option<M>>
where
M: Context<<M as Model>::Id, B> + 'static,
I: Into<Id<M, <M as Model>::Id>> + Send + Sync,
B: Backend,
{
match self {
Self::Id(id) => Ok(db.inner.get_model_by_id(&id.into()).await?),
Self::Model(model) => Ok(Some(model)),
}
}

pub fn id(&self) -> &Id<M, <M as Model>::Id> {
match self {
Self::Id(id) => id,
Self::Model(model) => model.id(),
}
}

pub fn take_id(self) -> Id<M, <M as Model>::Id> {
match self {
Self::Id(id) => id,
Self::Model(model) => model.id().clone(),
}
}
}

impl<M: Model> From<Id<M, <M as Model>::Id>> for Ref<M> {
fn from(id: Id<M, <M as Model>::Id>) -> Self {
Ref::Id(id)
}
}

impl<M: Model> From<Ref<M>> for Id<M, <M as Model>::Id> {
fn from(id: Ref<M>) -> Self {
match id {
Ref::Id(id) => id,
Ref::Model(model) => model.id().clone(),
}
}
}

impl<'a, M: Model> From<&'a Ref<M>> for &'a Id<M, <M as Model>::Id> {
fn from(id: &'a Ref<M>) -> Self {
match id {
Ref::Id(id) => id,
Ref::Model(model) => model.id(),
}
}
}

impl<M: Model> Serialize for Ref<M> {
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.id().serialize(serializer)
}
}

impl<'de, M: Model> Deserialize<'de> for Ref<M> {
fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Ref::Id(Id::deserialize(deserializer)?))
}
}

0 comments on commit 079588d

Please sign in to comment.