mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 20:32:48 +00:00
Move ical-related stuff to rustical_ical crate
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -3114,6 +3114,7 @@ dependencies = [
|
||||
"quick-xml",
|
||||
"rustical_dav",
|
||||
"rustical_dav_push",
|
||||
"rustical_ical",
|
||||
"rustical_store",
|
||||
"rustical_xml",
|
||||
"serde",
|
||||
@@ -3198,6 +3199,7 @@ dependencies = [
|
||||
name = "rustical_ical"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"derive_more 2.0.1",
|
||||
@@ -3206,6 +3208,8 @@ dependencies = [
|
||||
"regex",
|
||||
"rrule",
|
||||
"rustical_xml",
|
||||
"serde",
|
||||
"sha2",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"thiserror 2.0.12",
|
||||
|
||||
@@ -103,7 +103,7 @@ rustical_carddav = { path = "./crates/carddav/" }
|
||||
rustical_frontend = { path = "./crates/frontend/" }
|
||||
rustical_xml = { path = "./crates/xml/" }
|
||||
rustical_oidc = { path = "./crates/oidc/" }
|
||||
rustical_ical = { path = "./crates/ical/" }
|
||||
rustical_ical = { path = "./crates/ical/", features = ["actix"] }
|
||||
chrono-tz = "0.10"
|
||||
chrono-humanize = "0.2"
|
||||
rand = "0.8"
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::Error;
|
||||
use crate::calendar::prop::SupportedCalendarComponentSet;
|
||||
use actix_web::HttpResponse;
|
||||
use actix_web::web::{Data, Path};
|
||||
use rustical_ical::CalendarObjectType;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::calendar::CalendarObjectType;
|
||||
use rustical_store::{Calendar, CalendarStore};
|
||||
use rustical_xml::{Unparsed, XmlDeserialize, XmlDocument, XmlRootTag};
|
||||
use tracing::instrument;
|
||||
|
||||
@@ -11,7 +11,8 @@ use rustical_dav::{
|
||||
resource::{PrincipalUri, Resource},
|
||||
xml::{MultistatusElement, PropfindType, multistatus::ResponseElement},
|
||||
};
|
||||
use rustical_store::{CalendarObject, CalendarStore, auth::User};
|
||||
use rustical_ical::CalendarObject;
|
||||
use rustical_store::{CalendarStore, auth::User};
|
||||
use rustical_xml::XmlDeserialize;
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||
|
||||
@@ -2,8 +2,8 @@ use rustical_dav::{
|
||||
resource::{PrincipalUri, Resource},
|
||||
xml::{MultistatusElement, PropfindType},
|
||||
};
|
||||
use rustical_ical::UtcDateTime;
|
||||
use rustical_store::{CalendarObject, CalendarStore, auth::User, calendar_store::CalendarQuery};
|
||||
use rustical_ical::{CalendarObject, UtcDateTime};
|
||||
use rustical_store::{CalendarStore, auth::User, calendar_store::CalendarQuery};
|
||||
use rustical_xml::XmlDeserialize;
|
||||
use std::ops::Deref;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use derive_more::derive::{From, Into};
|
||||
use rustical_store::calendar::CalendarObjectType;
|
||||
use rustical_ical::CalendarObjectType;
|
||||
use rustical_xml::{XmlDeserialize, XmlSerialize};
|
||||
|
||||
#[derive(Debug, Clone, XmlSerialize, XmlDeserialize, PartialEq, From, Into)]
|
||||
|
||||
@@ -4,8 +4,9 @@ use actix_web::HttpResponse;
|
||||
use actix_web::http::header;
|
||||
use actix_web::http::header::HeaderValue;
|
||||
use actix_web::web::{Data, Path};
|
||||
use rustical_ical::CalendarObject;
|
||||
use rustical_store::CalendarStore;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::{CalendarObject, CalendarStore};
|
||||
use tracing::instrument;
|
||||
use tracing_actix_web::RootSpan;
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ use rustical_dav::{
|
||||
resource::{PrincipalUri, Resource, ResourceService},
|
||||
xml::Resourcetype,
|
||||
};
|
||||
use rustical_store::{CalendarObject, CalendarStore, auth::User};
|
||||
use rustical_ical::CalendarObject;
|
||||
use rustical_store::{CalendarStore, auth::User};
|
||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||
use serde::Deserialize;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -23,6 +23,9 @@ pub enum Error {
|
||||
|
||||
#[error(transparent)]
|
||||
XmlDecodeError(#[from] rustical_xml::XmlError),
|
||||
|
||||
#[error(transparent)]
|
||||
IcalError(#[from] rustical_ical::Error),
|
||||
}
|
||||
|
||||
impl actix_web::ResponseError for Error {
|
||||
@@ -30,9 +33,7 @@ impl actix_web::ResponseError for Error {
|
||||
match self {
|
||||
Error::StoreError(err) => match err {
|
||||
rustical_store::Error::NotFound => StatusCode::NOT_FOUND,
|
||||
rustical_store::Error::InvalidData(_) => StatusCode::BAD_REQUEST,
|
||||
rustical_store::Error::AlreadyExists => StatusCode::CONFLICT,
|
||||
rustical_store::Error::ParserError(_) => StatusCode::BAD_REQUEST,
|
||||
rustical_store::Error::ReadOnly => StatusCode::FORBIDDEN,
|
||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
},
|
||||
@@ -42,12 +43,14 @@ impl actix_web::ResponseError for Error {
|
||||
Error::XmlDecodeError(_) => StatusCode::BAD_REQUEST,
|
||||
Error::NotImplemented => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Error::NotFound => StatusCode::NOT_FOUND,
|
||||
Error::IcalError(err) => err.status_code(),
|
||||
}
|
||||
}
|
||||
fn error_response(&self) -> actix_web::HttpResponse<actix_web::body::BoxBody> {
|
||||
error!("Error: {self}");
|
||||
match self {
|
||||
Error::DavError(err) => err.error_response(),
|
||||
Error::IcalError(err) => err.error_response(),
|
||||
_ => HttpResponse::build(self.status_code()).body(self.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,3 +26,4 @@ chrono = { workspace = true }
|
||||
rustical_xml.workspace = true
|
||||
uuid.workspace = true
|
||||
rustical_dav_push.workspace = true
|
||||
rustical_ical.workspace = true
|
||||
|
||||
@@ -8,8 +8,9 @@ use actix_web::http::header::HeaderValue;
|
||||
use actix_web::web::{Data, Path};
|
||||
use rustical_dav::privileges::UserPrivilege;
|
||||
use rustical_dav::resource::Resource;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::AddressbookStore;
|
||||
use rustical_store::auth::User;
|
||||
use rustical_store::{AddressObject, AddressbookStore};
|
||||
use tracing::instrument;
|
||||
use tracing_actix_web::RootSpan;
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ use rustical_dav::{
|
||||
resource::{PrincipalUri, Resource, ResourceService},
|
||||
xml::Resourcetype,
|
||||
};
|
||||
use rustical_store::{AddressObject, AddressbookStore, auth::User};
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::{AddressbookStore, auth::User};
|
||||
use rustical_xml::{EnumUnitVariants, EnumVariants, XmlDeserialize, XmlSerialize};
|
||||
use serde::Deserialize;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -10,7 +10,8 @@ use rustical_dav::{
|
||||
resource::{PrincipalUri, Resource},
|
||||
xml::{MultistatusElement, PropfindType, multistatus::ResponseElement},
|
||||
};
|
||||
use rustical_store::{AddressObject, AddressbookStore, auth::User};
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::{AddressbookStore, auth::User};
|
||||
use rustical_xml::XmlDeserialize;
|
||||
|
||||
#[derive(XmlDeserialize, Clone, Debug, PartialEq)]
|
||||
|
||||
@@ -23,6 +23,9 @@ pub enum Error {
|
||||
|
||||
#[error(transparent)]
|
||||
XmlDecodeError(#[from] rustical_xml::XmlError),
|
||||
|
||||
#[error(transparent)]
|
||||
IcalError(#[from] rustical_ical::Error),
|
||||
}
|
||||
|
||||
impl actix_web::ResponseError for Error {
|
||||
@@ -30,9 +33,7 @@ impl actix_web::ResponseError for Error {
|
||||
match self {
|
||||
Error::StoreError(err) => match err {
|
||||
rustical_store::Error::NotFound => StatusCode::NOT_FOUND,
|
||||
rustical_store::Error::InvalidData(_) => StatusCode::BAD_REQUEST,
|
||||
rustical_store::Error::AlreadyExists => StatusCode::CONFLICT,
|
||||
rustical_store::Error::ParserError(_) => StatusCode::BAD_REQUEST,
|
||||
rustical_store::Error::ReadOnly => StatusCode::FORBIDDEN,
|
||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
},
|
||||
@@ -42,12 +43,14 @@ impl actix_web::ResponseError for Error {
|
||||
Error::XmlDecodeError(_) => StatusCode::BAD_REQUEST,
|
||||
Error::NotImplemented => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Error::NotFound => StatusCode::NOT_FOUND,
|
||||
Self::IcalError(err) => err.status_code(),
|
||||
}
|
||||
}
|
||||
fn error_response(&self) -> actix_web::HttpResponse<actix_web::body::BoxBody> {
|
||||
error!("Error: {self}");
|
||||
match self {
|
||||
Error::DavError(err) => err.error_response(),
|
||||
Error::IcalError(err) => err.error_response(),
|
||||
_ => HttpResponse::build(self.status_code()).body(self.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
description.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[features]
|
||||
actix = ["dep:actix-web"]
|
||||
|
||||
[dependencies]
|
||||
chrono.workspace = true
|
||||
chrono-tz.workspace = true
|
||||
@@ -17,3 +20,6 @@ regex.workspace = true
|
||||
strum.workspace = true
|
||||
strum_macros.workspace = true
|
||||
rrule = "0.14"
|
||||
serde.workspace = true
|
||||
sha2.workspace = true
|
||||
actix-web = { workspace = true, optional = true }
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::{CalDateTime, LOCAL_DATE};
|
||||
use crate::{CalendarObject, Error};
|
||||
use chrono::Datelike;
|
||||
use ical::parser::{
|
||||
Component,
|
||||
vcard::{self, component::VcardContact},
|
||||
};
|
||||
use rustical_ical::{CalDateTime, LOCAL_DATE};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{collections::HashMap, io::BufReader};
|
||||
|
||||
@@ -18,7 +18,7 @@ pub struct AddressObject {
|
||||
impl AddressObject {
|
||||
pub fn from_vcf(object_id: String, vcf: String) -> Result<Self, Error> {
|
||||
let mut parser = vcard::VcardParser::new(BufReader::new(vcf.as_bytes()));
|
||||
let vcard = parser.next().ok_or(Error::NotFound)??;
|
||||
let vcard = parser.next().ok_or(Error::MissingContact)??;
|
||||
if parser.next().is_some() {
|
||||
return Err(Error::InvalidData(
|
||||
"multiple vcards, only one allowed".to_owned(),
|
||||
35
crates/ical/src/error.rs
Normal file
35
crates/ical/src/error.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use crate::CalDateTimeError;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("Invalid ics/vcf input: {0}")]
|
||||
InvalidData(String),
|
||||
|
||||
#[error("Missing calendar")]
|
||||
MissingCalendar,
|
||||
|
||||
#[error("Missing contact")]
|
||||
MissingContact,
|
||||
|
||||
#[error(transparent)]
|
||||
ParserError(#[from] ical::parser::ParserError),
|
||||
|
||||
#[error(transparent)]
|
||||
CalDateTimeError(#[from] CalDateTimeError),
|
||||
|
||||
#[error(transparent)]
|
||||
RRuleError(#[from] rrule::RRuleError),
|
||||
}
|
||||
|
||||
#[cfg(feature = "actix")]
|
||||
impl actix_web::ResponseError for Error {
|
||||
fn status_code(&self) -> actix_web::http::StatusCode {
|
||||
match self {
|
||||
Self::InvalidData(_) => actix_web::http::StatusCode::BAD_REQUEST,
|
||||
Self::MissingCalendar | Self::MissingContact => {
|
||||
actix_web::http::StatusCode::BAD_REQUEST
|
||||
}
|
||||
_ => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
use crate::Error;
|
||||
use crate::{CalDateTime, ComponentMut, parse_duration};
|
||||
use chrono::{DateTime, Duration};
|
||||
use ical::{
|
||||
generator::IcalEvent,
|
||||
@@ -6,7 +7,6 @@ use ical::{
|
||||
property::Property,
|
||||
};
|
||||
use rrule::{RRule, RRuleSet};
|
||||
use rustical_ical::{CalDateTime, ComponentMut, parse_duration};
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -1,10 +1,8 @@
|
||||
mod calendar;
|
||||
mod event;
|
||||
mod journal;
|
||||
mod object;
|
||||
mod todo;
|
||||
|
||||
pub use calendar::*;
|
||||
pub use event::*;
|
||||
pub use journal::*;
|
||||
pub use object::*;
|
||||
@@ -1,10 +1,10 @@
|
||||
use super::{EventObject, JournalObject, TodoObject};
|
||||
use crate::CalDateTime;
|
||||
use crate::Error;
|
||||
use ical::{
|
||||
generator::{Emitter, IcalCalendar},
|
||||
parser::{Component, ical::component::IcalTimeZone},
|
||||
};
|
||||
use rustical_ical::CalDateTime;
|
||||
use serde::Serialize;
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{collections::HashMap, io::BufReader};
|
||||
@@ -66,7 +66,7 @@ pub struct CalendarObject {
|
||||
impl CalendarObject {
|
||||
pub fn from_ics(object_id: String, ics: String) -> Result<Self, Error> {
|
||||
let mut parser = ical::IcalParser::new(BufReader::new(ics.as_bytes()));
|
||||
let cal = parser.next().ok_or(Error::NotFound)??;
|
||||
let cal = parser.next().ok_or(Error::MissingCalendar)??;
|
||||
if parser.next().is_some() {
|
||||
return Err(Error::InvalidData(
|
||||
"multiple calendars, only one allowed".to_owned(),
|
||||
@@ -8,3 +8,12 @@ pub use timezone::*;
|
||||
|
||||
mod duration;
|
||||
pub use duration::parse_duration;
|
||||
|
||||
mod icalendar;
|
||||
pub use icalendar::*;
|
||||
|
||||
mod error;
|
||||
pub use error::Error;
|
||||
|
||||
mod address_object;
|
||||
pub use address_object::AddressObject;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
pub mod address_object;
|
||||
pub mod addressbook;
|
||||
|
||||
pub use address_object::*;
|
||||
pub use addressbook::*;
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::{
|
||||
Error,
|
||||
addressbook::{AddressObject, Addressbook},
|
||||
};
|
||||
use crate::{Error, addressbook::Addressbook};
|
||||
use async_trait::async_trait;
|
||||
use rustical_ical::AddressObject;
|
||||
|
||||
#[async_trait]
|
||||
pub trait AddressbookStore: Send + Sync + 'static {
|
||||
|
||||
@@ -38,7 +38,7 @@ impl TryFrom<&str> for PrincipalType {
|
||||
"ROOM" => Self::Room,
|
||||
"UNKNOWN" => Self::Unknown,
|
||||
_ => {
|
||||
return Err(crate::Error::InvalidData(
|
||||
return Err(crate::Error::InvalidPrincipalType(
|
||||
"Invalid principal type".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::CalendarObjectType;
|
||||
use crate::synctoken::format_synctoken;
|
||||
use chrono::NaiveDateTime;
|
||||
use rustical_ical::CalendarObjectType;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize)]
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::calendar::{Calendar, CalendarObject};
|
||||
use crate::error::Error;
|
||||
use crate::{Calendar, error::Error};
|
||||
use async_trait::async_trait;
|
||||
use chrono::NaiveDate;
|
||||
use rustical_ical::CalendarObject;
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct CalendarQuery {
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
AddressObject, Addressbook, AddressbookStore, Calendar, CalendarObject, CalendarStore, Error,
|
||||
calendar::CalendarObjectType,
|
||||
};
|
||||
use crate::{Addressbook, AddressbookStore, Calendar, CalendarStore, Error};
|
||||
use async_trait::async_trait;
|
||||
use derive_more::derive::Constructor;
|
||||
use rustical_ical::{AddressObject, CalendarObject, CalendarObjectType};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
#[derive(Constructor, Clone)]
|
||||
pub struct ContactBirthdayStore<AS: AddressbookStore>(Arc<AS>);
|
||||
@@ -85,7 +82,7 @@ impl<AS: AddressbookStore> CalendarStore for ContactBirthdayStore<AS> {
|
||||
) -> Result<(Vec<CalendarObject>, Vec<String>, i64), Error> {
|
||||
let (objects, deleted_objects, new_synctoken) =
|
||||
self.0.sync_changes(principal, cal_id, synctoken).await?;
|
||||
let objects: Result<Vec<Option<CalendarObject>>, Error> = objects
|
||||
let objects: Result<Vec<Option<CalendarObject>>, rustical_ical::Error> = objects
|
||||
.iter()
|
||||
.map(AddressObject::get_birthday_object)
|
||||
.collect();
|
||||
@@ -99,13 +96,13 @@ impl<AS: AddressbookStore> CalendarStore for ContactBirthdayStore<AS> {
|
||||
principal: &str,
|
||||
cal_id: &str,
|
||||
) -> Result<Vec<CalendarObject>, Error> {
|
||||
let objects: Result<Vec<HashMap<&'static str, CalendarObject>>, Error> = self
|
||||
.0
|
||||
.get_objects(principal, cal_id)
|
||||
.await?
|
||||
.iter()
|
||||
.map(AddressObject::get_significant_dates)
|
||||
.collect();
|
||||
let objects: Result<Vec<HashMap<&'static str, CalendarObject>>, rustical_ical::Error> =
|
||||
self.0
|
||||
.get_objects(principal, cal_id)
|
||||
.await?
|
||||
.iter()
|
||||
.map(AddressObject::get_significant_dates)
|
||||
.collect();
|
||||
let objects = objects?
|
||||
.into_iter()
|
||||
.flat_map(HashMap::into_values)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use actix_web::{ResponseError, http::StatusCode};
|
||||
use rustical_ical::CalDateTimeError;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
@@ -9,8 +8,8 @@ pub enum Error {
|
||||
#[error("Resource already exists and overwrite=false")]
|
||||
AlreadyExists,
|
||||
|
||||
#[error("Invalid ics/vcf input: {0}")]
|
||||
InvalidData(String),
|
||||
#[error("Invalid principal type: {0}")]
|
||||
InvalidPrincipalType(String),
|
||||
|
||||
#[error("Read-only")]
|
||||
ReadOnly,
|
||||
@@ -21,17 +20,11 @@ pub enum Error {
|
||||
#[error(transparent)]
|
||||
IO(#[from] std::io::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
ParserError(#[from] ical::parser::ParserError),
|
||||
|
||||
#[error(transparent)]
|
||||
Other(#[from] anyhow::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
CalDateTimeError(#[from] CalDateTimeError),
|
||||
|
||||
#[error(transparent)]
|
||||
RRuleError(#[from] rrule::RRuleError),
|
||||
IcalError(#[from] rustical_ical::Error),
|
||||
}
|
||||
|
||||
impl ResponseError for Error {
|
||||
@@ -39,8 +32,9 @@ impl ResponseError for Error {
|
||||
match self {
|
||||
Self::NotFound => StatusCode::NOT_FOUND,
|
||||
Self::AlreadyExists => StatusCode::CONFLICT,
|
||||
Self::InvalidData(_) => StatusCode::BAD_REQUEST,
|
||||
Self::ReadOnly => StatusCode::FORBIDDEN,
|
||||
Self::IcalError(err) => err.status_code(),
|
||||
Self::InvalidPrincipalType(_) => StatusCode::BAD_REQUEST,
|
||||
_ => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ pub mod calendar_store;
|
||||
pub mod error;
|
||||
pub use error::Error;
|
||||
pub mod auth;
|
||||
pub mod calendar;
|
||||
mod calendar;
|
||||
mod contact_birthday_store;
|
||||
mod secret;
|
||||
mod subscription_store;
|
||||
@@ -16,8 +16,8 @@ pub use contact_birthday_store::ContactBirthdayStore;
|
||||
pub use secret::Secret;
|
||||
pub use subscription_store::*;
|
||||
|
||||
pub use addressbook::{AddressObject, Addressbook};
|
||||
pub use calendar::{Calendar, CalendarObject};
|
||||
pub use addressbook::Addressbook;
|
||||
pub use calendar::Calendar;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CollectionOperationType {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use super::ChangeOperation;
|
||||
use async_trait::async_trait;
|
||||
use derive_more::derive::Constructor;
|
||||
use rustical_ical::AddressObject;
|
||||
use rustical_store::{
|
||||
AddressObject, Addressbook, AddressbookStore, CollectionOperation, CollectionOperationDomain,
|
||||
Addressbook, AddressbookStore, CollectionOperation, CollectionOperationDomain,
|
||||
CollectionOperationType, Error, synctoken::format_synctoken,
|
||||
};
|
||||
use sqlx::{Acquire, Executor, Sqlite, SqlitePool, Transaction};
|
||||
|
||||
@@ -2,11 +2,10 @@ use super::ChangeOperation;
|
||||
use async_trait::async_trait;
|
||||
use chrono::TimeDelta;
|
||||
use derive_more::derive::Constructor;
|
||||
use rustical_ical::CalDateTime;
|
||||
use rustical_store::calendar::CalendarObjectType;
|
||||
use rustical_ical::{CalDateTime, CalendarObject, CalendarObjectType};
|
||||
use rustical_store::calendar_store::CalendarQuery;
|
||||
use rustical_store::synctoken::format_synctoken;
|
||||
use rustical_store::{Calendar, CalendarObject, CalendarStore, Error};
|
||||
use rustical_store::{Calendar, CalendarStore, Error};
|
||||
use rustical_store::{CollectionOperation, CollectionOperationType};
|
||||
use sqlx::types::chrono::NaiveDateTime;
|
||||
use sqlx::{Acquire, Executor, Sqlite, SqlitePool, Transaction};
|
||||
@@ -23,7 +22,7 @@ impl TryFrom<CalendarObjectRow> for CalendarObject {
|
||||
type Error = rustical_store::Error;
|
||||
|
||||
fn try_from(value: CalendarObjectRow) -> Result<Self, Self::Error> {
|
||||
CalendarObject::from_ics(value.id, value.ics)
|
||||
Ok(CalendarObject::from_ics(value.id, value.ics)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ pub enum Error {
|
||||
|
||||
#[error(transparent)]
|
||||
StoreError(rustical_store::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
IcalError(#[from] rustical_ical::Error),
|
||||
}
|
||||
|
||||
impl From<sqlx::Error> for Error {
|
||||
@@ -27,6 +30,7 @@ impl From<Error> for rustical_store::Error {
|
||||
fn from(value: Error) -> Self {
|
||||
match value {
|
||||
Error::SqlxError(err) => Self::Other(err.into()),
|
||||
Error::IcalError(err) => Self::Other(err.into()),
|
||||
Error::StoreError(err) => err,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user