mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 19:22:26 +00:00
simplify resourcetype
This commit is contained in:
@@ -39,14 +39,6 @@ pub struct SupportedCalendarData {
|
|||||||
calendar_data: CalendarData,
|
calendar_data: CalendarData,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {
|
|
||||||
#[serde(rename = "C:calendar", alias = "calendar")]
|
|
||||||
calendar: (),
|
|
||||||
collection: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum ReportMethod {
|
pub enum ReportMethod {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::methods::mkcalendar::route_mkcalendar;
|
use super::methods::mkcalendar::route_mkcalendar;
|
||||||
use super::methods::report::route_report_calendar;
|
use super::methods::report::route_report_calendar;
|
||||||
use super::prop::{
|
use super::prop::{
|
||||||
Resourcetype, SupportedCalendarComponent, SupportedCalendarComponentSet, SupportedCalendarData,
|
SupportedCalendarComponent, SupportedCalendarComponentSet, SupportedCalendarData,
|
||||||
SupportedReportSet,
|
SupportedReportSet,
|
||||||
};
|
};
|
||||||
use crate::calendar_object::resource::CalendarObjectResource;
|
use crate::calendar_object::resource::CalendarObjectResource;
|
||||||
@@ -83,7 +83,7 @@ pub enum CalendarProp {
|
|||||||
|
|
||||||
#[serde(skip_deserializing, untagged)]
|
#[serde(skip_deserializing, untagged)]
|
||||||
#[from]
|
#[from]
|
||||||
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
|
ExtCommonProperties(CommonPropertiesProp),
|
||||||
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[default]
|
#[default]
|
||||||
@@ -97,9 +97,12 @@ impl Resource for CalendarResource {
|
|||||||
type PropName = CalendarPropName;
|
type PropName = CalendarPropName;
|
||||||
type Prop = CalendarProp;
|
type Prop = CalendarProp;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&["collection", "C:calendar"]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
_rmap: &ResourceMap,
|
_rmap: &ResourceMap,
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub enum CalendarObjectProp {
|
|||||||
|
|
||||||
#[serde(skip_deserializing, untagged)]
|
#[serde(skip_deserializing, untagged)]
|
||||||
#[from]
|
#[from]
|
||||||
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
|
ExtCommonProperties(CommonPropertiesProp),
|
||||||
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[default]
|
#[default]
|
||||||
@@ -54,16 +54,15 @@ pub struct CalendarObjectResource {
|
|||||||
pub principal: String,
|
pub principal: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {}
|
|
||||||
|
|
||||||
impl Resource for CalendarObjectResource {
|
impl Resource for CalendarObjectResource {
|
||||||
type PropName = CalendarObjectPropName;
|
type PropName = CalendarObjectPropName;
|
||||||
type Prop = CalendarObjectProp;
|
type Prop = CalendarObjectProp;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -25,13 +25,6 @@ pub struct PrincipalResource {
|
|||||||
principal: String,
|
principal: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default, Debug, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {
|
|
||||||
principal: (),
|
|
||||||
collection: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Serialize, From, PartialEq)]
|
#[derive(Default, Deserialize, Serialize, From, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum PrincipalProp {
|
pub enum PrincipalProp {
|
||||||
@@ -47,7 +40,7 @@ pub enum PrincipalProp {
|
|||||||
|
|
||||||
#[serde(skip_deserializing, untagged)]
|
#[serde(skip_deserializing, untagged)]
|
||||||
#[from]
|
#[from]
|
||||||
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
|
ExtCommonProperties(CommonPropertiesProp),
|
||||||
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[default]
|
#[default]
|
||||||
@@ -73,9 +66,12 @@ impl Resource for PrincipalResource {
|
|||||||
type PropName = PrincipalPropName;
|
type PropName = PrincipalPropName;
|
||||||
type Prop = PrincipalProp;
|
type Prop = PrincipalProp;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&["collection", "principal"]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
rmap: &ResourceMap,
|
rmap: &ResourceMap,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub enum AddressObjectProp {
|
|||||||
|
|
||||||
#[serde(skip_deserializing, untagged)]
|
#[serde(skip_deserializing, untagged)]
|
||||||
#[from]
|
#[from]
|
||||||
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
|
ExtCommonProperties(CommonPropertiesProp),
|
||||||
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[default]
|
#[default]
|
||||||
@@ -55,17 +55,16 @@ pub struct AddressObjectResource {
|
|||||||
pub principal: String,
|
pub principal: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {}
|
|
||||||
|
|
||||||
impl Resource for AddressObjectResource {
|
impl Resource for AddressObjectResource {
|
||||||
type PropName = AddressObjectPropName;
|
type PropName = AddressObjectPropName;
|
||||||
type Prop = AddressObjectProp;
|
type Prop = AddressObjectProp;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
_rmap: &ResourceMap,
|
_rmap: &ResourceMap,
|
||||||
|
|||||||
@@ -33,14 +33,6 @@ impl Default for SupportedAddressData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {
|
|
||||||
#[serde(rename = "CARD:addressbook", alias = "addressbook")]
|
|
||||||
addressbook: (),
|
|
||||||
collection: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum ReportMethod {
|
pub enum ReportMethod {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use super::methods::mkcol::route_mkcol;
|
use super::methods::mkcol::route_mkcol;
|
||||||
use super::methods::report::route_report_addressbook;
|
use super::methods::report::route_report_addressbook;
|
||||||
use super::prop::{Resourcetype, SupportedAddressData, SupportedReportSet};
|
use super::prop::{SupportedAddressData, SupportedReportSet};
|
||||||
use crate::address_object::resource::AddressObjectResource;
|
use crate::address_object::resource::AddressObjectResource;
|
||||||
use crate::principal::PrincipalResource;
|
use crate::principal::PrincipalResource;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
@@ -68,7 +68,7 @@ pub enum AddressbookProp {
|
|||||||
|
|
||||||
#[serde(skip_deserializing, untagged)]
|
#[serde(skip_deserializing, untagged)]
|
||||||
#[from]
|
#[from]
|
||||||
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
|
ExtCommonProperties(CommonPropertiesProp),
|
||||||
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[default]
|
#[default]
|
||||||
@@ -82,9 +82,12 @@ impl Resource for AddressbookResource {
|
|||||||
type PropName = AddressbookPropName;
|
type PropName = AddressbookPropName;
|
||||||
type Prop = AddressbookProp;
|
type Prop = AddressbookProp;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&["collection", "CARD:addressbook"]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
_rmap: &ResourceMap,
|
_rmap: &ResourceMap,
|
||||||
|
|||||||
@@ -25,13 +25,6 @@ pub struct PrincipalResource {
|
|||||||
principal: String,
|
principal: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default, Debug, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {
|
|
||||||
principal: (),
|
|
||||||
collection: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Deserialize, Serialize, From, PartialEq)]
|
#[derive(Default, Deserialize, Serialize, From, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum PrincipalProp {
|
pub enum PrincipalProp {
|
||||||
@@ -47,7 +40,7 @@ pub enum PrincipalProp {
|
|||||||
|
|
||||||
#[serde(skip_deserializing, untagged)]
|
#[serde(skip_deserializing, untagged)]
|
||||||
#[from]
|
#[from]
|
||||||
ExtCommonProperties(CommonPropertiesProp<Resourcetype>),
|
ExtCommonProperties(CommonPropertiesProp),
|
||||||
|
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[default]
|
#[default]
|
||||||
@@ -73,9 +66,12 @@ impl Resource for PrincipalResource {
|
|||||||
type PropName = PrincipalPropName;
|
type PropName = PrincipalPropName;
|
||||||
type Prop = PrincipalProp;
|
type Prop = PrincipalProp;
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
type PrincipalResource = PrincipalResource;
|
type PrincipalResource = PrincipalResource;
|
||||||
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&["collection", "principal"]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
rmap: &ResourceMap,
|
rmap: &ResourceMap,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
extension::ResourceExtension,
|
extension::ResourceExtension,
|
||||||
privileges::UserPrivilegeSet,
|
privileges::UserPrivilegeSet,
|
||||||
resource::{InvalidProperty, Resource, ResourceType},
|
resource::{InvalidProperty, Resource},
|
||||||
xml::HrefElement,
|
xml::{HrefElement, Resourcetype},
|
||||||
};
|
};
|
||||||
use actix_web::dev::ResourceMap;
|
use actix_web::dev::ResourceMap;
|
||||||
use rustical_store::auth::User;
|
use rustical_store::auth::User;
|
||||||
@@ -21,10 +21,10 @@ impl<R: Resource> Default for CommonPropertiesExtension<R> {
|
|||||||
|
|
||||||
#[derive(Deserialize, Serialize, PartialEq)]
|
#[derive(Deserialize, Serialize, PartialEq)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum CommonPropertiesProp<RT: ResourceType> {
|
pub enum CommonPropertiesProp {
|
||||||
// WebDAV (RFC 2518)
|
// WebDAV (RFC 2518)
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
Resourcetype(RT),
|
Resourcetype(Resourcetype),
|
||||||
|
|
||||||
// WebDAV Current Principal Extension (RFC 5397)
|
// WebDAV Current Principal Extension (RFC 5397)
|
||||||
CurrentUserPrincipal(HrefElement),
|
CurrentUserPrincipal(HrefElement),
|
||||||
@@ -37,7 +37,7 @@ pub enum CommonPropertiesProp<RT: ResourceType> {
|
|||||||
Invalid,
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<RT: ResourceType> InvalidProperty for CommonPropertiesProp<RT> {
|
impl InvalidProperty for CommonPropertiesProp {
|
||||||
fn invalid_property(&self) -> bool {
|
fn invalid_property(&self) -> bool {
|
||||||
matches!(self, Self::Invalid)
|
matches!(self, Self::Invalid)
|
||||||
}
|
}
|
||||||
@@ -54,9 +54,9 @@ pub enum CommonPropertiesPropName {
|
|||||||
|
|
||||||
impl<R: Resource> ResourceExtension<R> for CommonPropertiesExtension<R>
|
impl<R: Resource> ResourceExtension<R> for CommonPropertiesExtension<R>
|
||||||
where
|
where
|
||||||
R::Prop: From<CommonPropertiesProp<R::ResourceType>>,
|
R::Prop: From<CommonPropertiesProp>,
|
||||||
{
|
{
|
||||||
type Prop = CommonPropertiesProp<R::ResourceType>;
|
type Prop = CommonPropertiesProp;
|
||||||
type PropName = CommonPropertiesPropName;
|
type PropName = CommonPropertiesPropName;
|
||||||
type Error = R::Error;
|
type Error = R::Error;
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ where
|
|||||||
) -> Result<Self::Prop, Self::Error> {
|
) -> Result<Self::Prop, Self::Error> {
|
||||||
Ok(match prop {
|
Ok(match prop {
|
||||||
CommonPropertiesPropName::Resourcetype => {
|
CommonPropertiesPropName::Resourcetype => {
|
||||||
CommonPropertiesProp::Resourcetype(R::ResourceType::default())
|
CommonPropertiesProp::Resourcetype(Resourcetype(R::get_resourcetype()))
|
||||||
}
|
}
|
||||||
CommonPropertiesPropName::CurrentUserPrincipal => {
|
CommonPropertiesPropName::CurrentUserPrincipal => {
|
||||||
CommonPropertiesProp::CurrentUserPrincipal(
|
CommonPropertiesProp::CurrentUserPrincipal(
|
||||||
|
|||||||
@@ -29,10 +29,11 @@ impl<T: Serialize + for<'de> Deserialize<'de>> ResourceType for T {}
|
|||||||
|
|
||||||
pub trait Resource: Clone + 'static {
|
pub trait Resource: Clone + 'static {
|
||||||
type PropName: ResourcePropName;
|
type PropName: ResourcePropName;
|
||||||
type Prop: ResourceProp + From<CommonPropertiesProp<Self::ResourceType>> + PartialEq;
|
type Prop: ResourceProp + From<CommonPropertiesProp> + PartialEq;
|
||||||
type Error: ResponseError + From<crate::Error>;
|
type Error: ResponseError + From<crate::Error>;
|
||||||
type PrincipalResource: Resource;
|
type PrincipalResource: Resource;
|
||||||
type ResourceType: Default + Serialize + for<'de> Deserialize<'de>;
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str];
|
||||||
|
|
||||||
fn list_extensions() -> Vec<impl ResourceExtension<Self>> {
|
fn list_extensions() -> Vec<impl ResourceExtension<Self>> {
|
||||||
vec![CommonPropertiesExtension::default()]
|
vec![CommonPropertiesExtension::default()]
|
||||||
@@ -122,7 +123,7 @@ pub trait Resource: Clone + 'static {
|
|||||||
Error::BadRequest("allprop MUST be the only queried prop".to_owned()).into(),
|
Error::BadRequest("allprop MUST be the only queried prop".to_owned()).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
props = Self::list_props();
|
props = Self::list_props().to_vec();
|
||||||
for extension in Self::list_extensions() {
|
for extension in Self::list_extensions() {
|
||||||
let ext_props: Vec<&str> = extension.list_props().into();
|
let ext_props: Vec<&str> = extension.list_props().into();
|
||||||
props.extend(ext_props);
|
props.extend(ext_props);
|
||||||
|
|||||||
@@ -5,17 +5,10 @@ use actix_web::dev::ResourceMap;
|
|||||||
use actix_web::HttpRequest;
|
use actix_web::HttpRequest;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rustical_store::auth::User;
|
use rustical_store::auth::User;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::any::type_name;
|
use std::any::type_name;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use strum::{EnumString, VariantNames};
|
use strum::{EnumString, VariantNames};
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default, Debug, PartialEq)]
|
|
||||||
#[serde(rename_all = "kebab-case")]
|
|
||||||
pub struct Resourcetype {
|
|
||||||
collection: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RootResource<PR: Resource>(PhantomData<PR>);
|
pub struct RootResource<PR: Resource>(PhantomData<PR>);
|
||||||
|
|
||||||
@@ -31,11 +24,14 @@ pub enum RootResourcePropName {}
|
|||||||
|
|
||||||
impl<PR: Resource> Resource for RootResource<PR> {
|
impl<PR: Resource> Resource for RootResource<PR> {
|
||||||
type PropName = RootResourcePropName;
|
type PropName = RootResourcePropName;
|
||||||
type Prop = CommonPropertiesProp<Self::ResourceType>;
|
type Prop = CommonPropertiesProp;
|
||||||
type Error = PR::Error;
|
type Error = PR::Error;
|
||||||
type ResourceType = Resourcetype;
|
|
||||||
type PrincipalResource = PR;
|
type PrincipalResource = PR;
|
||||||
|
|
||||||
|
fn get_resourcetype() -> &'static [&'static str] {
|
||||||
|
&["collection"]
|
||||||
|
}
|
||||||
|
|
||||||
fn get_prop(
|
fn get_prop(
|
||||||
&self,
|
&self,
|
||||||
_rmap: &ResourceMap,
|
_rmap: &ResourceMap,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
pub mod multistatus;
|
pub mod multistatus;
|
||||||
|
mod resourcetype;
|
||||||
pub mod tag_list;
|
pub mod tag_list;
|
||||||
pub mod tag_name;
|
pub mod tag_name;
|
||||||
|
|
||||||
@@ -7,6 +8,8 @@ pub use multistatus::MultistatusElement;
|
|||||||
pub use tag_list::TagList;
|
pub use tag_list::TagList;
|
||||||
pub use tag_name::TagName;
|
pub use tag_name::TagName;
|
||||||
|
|
||||||
|
pub use resourcetype::Resourcetype;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, From, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, From, PartialEq)]
|
||||||
|
|||||||
46
crates/dav/src/xml/resourcetype.rs
Normal file
46
crates/dav/src/xml/resourcetype.rs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
use serde::de::{MapAccess, Visitor};
|
||||||
|
use serde::ser::SerializeMap;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct Resourcetype(pub &'static [&'static str]);
|
||||||
|
|
||||||
|
struct ResourcetypeVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for ResourcetypeVisitor {
|
||||||
|
type Value = Resourcetype;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("TagList")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: MapAccess<'de>,
|
||||||
|
{
|
||||||
|
while map.next_key::<String>()?.is_some() {}
|
||||||
|
Ok(Resourcetype(&[]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Resourcetype {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
deserializer.deserialize_map(ResourcetypeVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Resourcetype {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
let mut map = serializer.serialize_map(Some(self.0.len()))?;
|
||||||
|
for entry in self.0 {
|
||||||
|
map.serialize_entry(entry, &())?;
|
||||||
|
}
|
||||||
|
map.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user