instant_epp/extensions/frnic/
contact.rs

1//! Types for EPP FRNIC contact requests
2use instant_xml::{Id, ToXml};
3use std::borrow::Cow;
4
5use crate::request::{Extension, Transaction};
6
7use super::{Create, Ext, XMLNS};
8
9impl<'a> Transaction<Ext<Create<ContactCreate<'a>>>> for crate::contact::create::ContactCreate<'a> {}
10
11impl<'a> Extension for Ext<Create<ContactCreate<'a>>> {
12    type Response = ();
13}
14
15/// For french TLDs, a contact is either an individual (PP) or a legal
16/// entity (PM). We use the `ContactCreate` extension to differentiate
17/// between the creation of a PP and a PM.
18#[derive(Debug)]
19pub enum ContactCreate<'a> {
20    /// This contact is an individual.
21    NaturalPerson {
22        /// First name of the contact. The `<contact:name>` element
23        /// will be the family name.
24        first_name: Cow<'a, str>,
25    },
26    /// This contact is a legal entity.
27    LegalEntity(Box<LegalEntityInfos<'a>>),
28}
29
30impl<'a> From<ContactCreate<'a>> for Ext<Create<ContactCreate<'a>>> {
31    fn from(data: ContactCreate<'a>) -> Self {
32        Ext {
33            data: Create { data },
34        }
35    }
36}
37
38impl<'a> ContactCreate<'a> {
39    pub fn new_natural_person(first_name: &'a str) -> Self {
40        Self::NaturalPerson {
41            first_name: first_name.into(),
42        }
43    }
44
45    pub fn new_company(
46        siren: Option<&'a str>,
47        vat: Option<&'a str>,
48        trademark: Option<&'a str>,
49        duns: Option<&'a str>,
50        local: Option<&'a str>,
51    ) -> Self {
52        Self::LegalEntity(Box::new(LegalEntityInfos {
53            legal_status: LegalStatus::Company,
54            siren: siren.map(|s| s.into()),
55            vat: vat.map(|v| v.into()),
56            trademark: trademark.map(|t| t.into()),
57            asso: None,
58            duns: duns.map(|d| d.into()),
59            local: local.map(|l| l.into()),
60        }))
61    }
62
63    pub fn new_non_profit(
64        waldec: Option<&'a str>,
65        declaration: Option<&'a str>,
66        publication: Option<Publication<'a>>,
67    ) -> Self {
68        Self::LegalEntity(Box::new(LegalEntityInfos {
69            legal_status: LegalStatus::Association,
70            siren: None,
71            vat: None,
72            trademark: None,
73            asso: Some(Association {
74                waldec: waldec.map(|w| w.into()),
75                declaration: declaration.map(|d| d.into()),
76                publication,
77            }),
78            duns: None,
79            local: None,
80        }))
81    }
82}
83
84impl<'a> ToXml for ContactCreate<'a> {
85    fn serialize<W: core::fmt::Write + ?Sized>(
86        &self,
87        _: Option<Id<'_>>,
88        serializer: &mut instant_xml::Serializer<'_, W>,
89    ) -> Result<(), instant_xml::Error> {
90        let contact_nc_name = "contact";
91        let prefix = serializer.write_start(contact_nc_name, XMLNS)?;
92        serializer.end_start()?;
93        match self {
94            Self::NaturalPerson { first_name } => {
95                let first_name_nc_name = "firstName";
96                let prefix = serializer.write_start(first_name_nc_name, XMLNS)?;
97                serializer.end_start()?;
98                first_name.serialize(None, serializer)?;
99                serializer.write_close(prefix, first_name_nc_name)?;
100            }
101            Self::LegalEntity(infos) => infos.serialize(None, serializer)?,
102        }
103        serializer.write_close(prefix, contact_nc_name)?;
104        Ok(())
105    }
106}
107
108#[derive(Debug, ToXml)]
109#[xml(rename = "legalEntityInfos", ns(XMLNS))]
110pub struct LegalEntityInfos<'a> {
111    pub legal_status: LegalStatus<'a>,
112    pub siren: Option<Cow<'a, str>>,
113    pub vat: Option<Cow<'a, str>>,
114    pub trademark: Option<Cow<'a, str>>,
115    pub asso: Option<Association<'a>>,
116    pub duns: Option<Cow<'a, str>>,
117    pub local: Option<Cow<'a, str>>,
118}
119
120#[derive(Debug)]
121pub enum LegalStatus<'a> {
122    Company,
123    Association,
124    Other(Cow<'a, str>),
125}
126
127impl<'a> ToXml for LegalStatus<'a> {
128    fn serialize<W: core::fmt::Write + ?Sized>(
129        &self,
130        _field: Option<Id<'_>>,
131        serializer: &mut instant_xml::Serializer<W>,
132    ) -> Result<(), instant_xml::Error> {
133        let ncname = "legalStatus";
134        let (s, data) = match self {
135            LegalStatus::Company => ("company", None),
136            LegalStatus::Association => ("association", None),
137            LegalStatus::Other(text) => ("other", Some(&text.as_ref()[2..])),
138        };
139        let prefix = serializer.write_start(ncname, XMLNS)?;
140        debug_assert_eq!(prefix, None);
141        serializer.write_attr("s", XMLNS, s)?;
142        if let Some(text) = data {
143            serializer.end_start()?;
144            text.serialize(None, serializer)?;
145            serializer.write_close(prefix, ncname)?;
146        } else {
147            serializer.end_empty()?;
148        }
149        Ok(())
150    }
151}
152
153/// Contains information that permits the identification of associations.
154#[derive(Debug, ToXml)]
155#[xml(rename = "asso", ns(XMLNS))]
156pub struct Association<'a> {
157    /// The Waldec registration number. "Waldec" is the acronym for
158    /// the french "[Web des associations librement
159    /// déclarées](https://www.associations.gouv.fr/le-rna-repertoire-national-des-associations.html)"
160    pub waldec: Option<Cow<'a, str>>,
161    /// Date of declaration to the prefecture
162    #[xml(rename = "decl")]
163    pub declaration: Option<Cow<'a, str>>,
164    /// Information of publication in the official gazette
165    #[xml(rename = "publ")]
166    pub publication: Option<Publication<'a>>,
167}
168
169/// Holds information about the publication in the
170/// official gazette for the association.
171#[derive(Debug, ToXml)]
172#[xml(rename = "publ", ns(XMLNS))]
173pub struct Publication<'a> {
174    /// Page number of the announcement
175    #[xml(attribute)]
176    pub page: u32,
177    #[xml(attribute)]
178    /// Number of the announcement
179    pub announce: u32,
180    /// Date of publication
181    #[xml(direct)]
182    pub date: Cow<'a, str>,
183}