Manos Pitsidianakis 2022-05-02 19:23:34 +03:00
parent 267d39d2d8
commit 4561f4f48d
6 changed files with 122 additions and 24 deletions

View File

@ -243,6 +243,7 @@ fn run_app(opt: Opt) -> Result<()> {
db.add_member(
list.pk,
ListMembership {
pk: 0,
list: list.pk,
name,
address,

View File

@ -31,7 +31,7 @@ pub struct Database {
}
impl Database {
pub fn list_lists(&self) -> Result<Vec<MailingList>> {
pub fn list_lists(&self) -> Result<Vec<DbVal<MailingList>>> {
/*
let ret = mailing_lists::table.load(&self.connection)?;
Ok(ret)
@ -39,7 +39,7 @@ impl Database {
Ok(vec![])
}
pub fn get_list(&self, pk: i32) -> Result<Option<MailingList>> {
pub fn get_list(&self, pk: i32) -> Result<Option<DbVal<MailingList>>> {
/*
let ret = mailing_lists::table
.filter(mailing_lists::pk.eq(pk))
@ -50,7 +50,7 @@ impl Database {
Ok(None)
}
pub fn create_list(&self, new_val: MailingList) -> Result<i32> {
pub fn create_list(&self, new_val: MailingList) -> Result<DbVal<MailingList>> {
let pk: i32 = 1;
/*
let pk: i32 = self.connection.transaction::<_, _, _>(|| {
@ -65,7 +65,8 @@ impl Database {
})?;
*/
trace!("create_list {}.", new_val,);
Ok(pk)
//Ok(pk)
todo!()
}
pub fn update_list(&self, set: MailingListChangeset) -> Result<()> {
@ -77,7 +78,7 @@ impl Database {
Ok(())
}
pub fn get_list_policy(&self, pk: i32) -> Result<Option<PostPolicy>> {
pub fn get_list_policy(&self, pk: i32) -> Result<Option<DbVal<PostPolicy>>> {
/*
let ret = post_policy::table
.filter(post_policy::list.eq(pk))
@ -88,7 +89,7 @@ impl Database {
Ok(None)
}
pub fn get_list_owners(&self, pk: i32) -> Result<Vec<ListOwner>> {
pub fn get_list_owners(&self, pk: i32) -> Result<Vec<DbVal<ListOwner>>> {
/*
let ret = list_owner::table
.filter(list_owner::list.eq(pk))
@ -98,7 +99,7 @@ impl Database {
Ok(vec![])
}
pub fn list_members(&self, pk: i32) -> Result<Vec<ListMembership>> {
pub fn list_members(&self, pk: i32) -> Result<Vec<DbVal<ListMembership>>> {
/*
let ret = membership::table
.filter(membership::list.eq(pk))
@ -178,7 +179,7 @@ impl Database {
pub fn get_list_filters(
&self,
_list: &MailingList,
_list: &DbVal<MailingList>,
) -> Vec<Box<dyn crate::mail::message_filters::PostFilter>> {
use crate::mail::message_filters::*;
vec![
@ -353,7 +354,7 @@ impl Database {
pub fn request(
&self,
list: &MailingList,
list: &DbVal<MailingList>,
request: ListRequest,
env: &Envelope,
_raw: &[u8],
@ -373,6 +374,7 @@ impl Database {
.unwrap_or(false);
for f in env.from() {
let membership = ListMembership {
pk: 0,
list: list.pk,
address: f.get_email(),
name: f.get_display_name(),

View File

@ -32,9 +32,9 @@ pub enum PostAction {
#[derive(Debug)]
pub struct ListContext<'list> {
pub list: &'list MailingList,
pub list_owners: Vec<ListOwner>,
pub memberships: &'list [ListMembership],
pub policy: Option<PostPolicy>,
pub list_owners: Vec<DbVal<ListOwner>>,
pub memberships: &'list [DbVal<ListMembership>],
pub policy: Option<DbVal<PostPolicy>>,
pub scheduled_jobs: Vec<MailJob>,
}

View File

@ -44,10 +44,7 @@ impl PostFilter for PostRightsCheck {
let owner_addresses = ctx
.list_owners
.iter()
.map(|lo| {
let lm: ListMembership = lo.clone().into();
lm.into_address()
})
.map(|lo| lo.into_address())
.collect::<Vec<Address>>();
trace!("Owner addresses are: {:#?}", &owner_addresses);
trace!("Envelope from is: {:?}", &post.from);

View File

@ -18,9 +18,81 @@
*/
use super::*;
use db::Database;
pub mod changesets;
use melib::email::Address;
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, Value, ValueRef};
pub trait DbModel:
serde::Serialize + serde::de::DeserializeOwned + std::fmt::Display + std::fmt::Debug
{
}
impl<I: serde::Serialize + serde::de::DeserializeOwned + std::fmt::Display + std::fmt::Debug>
DbModel for I
{
}
pub struct DbVal<T: DbModel>(pub T, pub i32);
impl<T: DbModel> serde::Serialize for DbVal<T> {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
impl<T: DbModel> std::ops::Deref for DbVal<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T: DbModel> std::fmt::Display for DbVal<T> {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{}", self.0)
}
}
impl<T: DbModel> std::fmt::Debug for DbVal<T>
where
T: std::fmt::Debug,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{:?}", self.0)
}
}
macro_rules! sql_json_impl {
($t:ty) => {
impl $t {
pub fn get(db: &Database, pk: i32) -> Result<Self> {
todo!()
}
}
impl ToSql for $t {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::Owned(Value::Text(
serde_json::to_string(&self).unwrap(),
)))
}
}
impl FromSql for $t {
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
Ok(
serde_json::from_str(value.as_str_or_null()?.ok_or(FromSqlError::InvalidType)?)
.unwrap(),
)
}
}
};
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MailingList {
@ -32,13 +104,7 @@ pub struct MailingList {
pub archive_url: Option<String>,
}
impl rusqlite::types::ToSql for MailingList {
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
Ok(rusqlite::types::ToSqlOutput::Owned(
rusqlite::types::Value::Text(serde_json::to_string(&self).unwrap()),
))
}
}
sql_json_impl!(MailingList);
impl std::fmt::Display for MailingList {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
@ -86,6 +152,7 @@ impl MailingList {
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ListMembership {
pub pk: i32,
pub list: i32,
pub address: String,
pub name: Option<String>,
@ -97,6 +164,8 @@ pub struct ListMembership {
pub enabled: bool,
}
sql_json_impl!(ListMembership);
impl std::fmt::Display for ListMembership {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
@ -129,6 +198,8 @@ pub struct PostPolicy {
pub approval_needed: bool,
}
sql_json_impl!(PostPolicy);
impl std::fmt::Display for PostPolicy {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{:?}", self)
@ -143,6 +214,8 @@ pub struct ListOwner {
pub name: Option<String>,
}
sql_json_impl!(ListOwner);
impl std::fmt::Display for ListOwner {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "[#{} {}] {}", self.pk, self.list, self.into_address())
@ -152,6 +225,7 @@ impl std::fmt::Display for ListOwner {
impl From<ListOwner> for ListMembership {
fn from(val: ListOwner) -> ListMembership {
ListMembership {
pk: 0,
list: val.list,
address: val.address,
name: val.name,
@ -171,13 +245,15 @@ impl ListOwner {
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub enum ListRequest {
Subscribe,
Unsubscribe,
Other(String),
}
sql_json_impl!(ListRequest);
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct NewListPost<'s> {
pub list: i32,

View File

@ -58,3 +58,25 @@ pub struct ListOwnerChangeset {
pub address: Option<String>,
pub name: Option<Option<String>>,
}
impl std::fmt::Display for MailingListChangeset {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{:?}", self)
}
}
impl std::fmt::Display for ListMembershipChangeset {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{:?}", self)
}
}
impl std::fmt::Display for PostPolicyChangeset {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{:?}", self)
}
}
impl std::fmt::Display for ListOwnerChangeset {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{:?}", self)
}
}