agendas.rs 9.87 KB
Newer Older
1
use chrono::{DateTime, FixedOffset};
2

3
use acteurs::Acteur;
4
use commun::{CycleDeVie, EmptyChoice, Ident, ListePays, Uid, XmlNamespace};
5 6
use contexts::Context;
use organes::Organe;
7
use points_odj::{PointOdj, PointsOdj};
8 9
use serde_utils::{map_to_vec, str_to_bool, str_to_option_bool, str_to_vec};

10
#[derive(Clone, Debug, Deserialize)]
11
#[serde(deny_unknown_fields)]
12
pub struct ActeurDemandeur {
13 14 15 16 17
    pub nom: String,
    #[serde(rename = "acteurRef")]
    pub acteur_ref: String,
}

18
#[derive(Debug, Deserialize)]
19 20 21 22 23
#[serde(deny_unknown_fields)]
pub struct AgendaJsonWrapper {
    pub reunions: Reunions,
}

24
#[derive(Clone, Debug, Deserialize)]
25 26 27
#[serde(deny_unknown_fields)]
pub struct Demandeurs {
    #[serde(default, deserialize_with = "map_to_vec", rename = "acteur")]
28 29
    pub acteurs: Vec<ActeurDemandeur>,
    pub organe: Option<OrganeDemandeur>,
30 31
}

32 33 34 35
impl Demandeurs {
    pub fn acteurs<'a>(&self, context: &'a Context) -> Vec<&'a Acteur> {
        self.acteurs_refs()
            .iter()
36
            .filter_map(|acteur_ref| context.get_acteur_at_uid(acteur_ref))
37 38 39 40 41 42 43 44 45 46 47 48 49
            .collect()
    }

    pub fn acteurs_refs(&self) -> Vec<&str> {
        self.acteurs
            .iter()
            .map(|acteur| acteur.acteur_ref.as_ref())
            .collect()
    }

    pub fn organe<'a>(&self, context: &'a Context) -> Option<&'a Organe> {
        match self.organe_ref() {
            None => None,
50
            Some(ref organe_ref) => context.get_organe_at_uid(organe_ref),
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
        }
    }

    pub fn organe_ref(&self) -> Option<&str> {
        match self.organe {
            None => None,
            Some(ref organe) => Some(&organe.organe_ref),
        }
    }
}

graphql_object!(Demandeurs: Context |&self| {
    field acteurs(&executor) -> Vec<&Acteur> {
        self.acteurs(&executor.context())
    }

    field acteurs_refs() -> Vec<&str> {
        self.acteurs_refs()
    }

    field organe(&executor) -> Option<&Organe> {
        self.organe(&executor.context())
    }

    field organe_ref() -> Option<&str> {
        self.organe_ref()
    }
});

80 81 82 83
#[derive(Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
pub struct Identifiants {
    #[serde(rename = "DateSeance")]
84
    // TODO: Date<FixedOffset> type is not able to deserialize dates with timezone (`YYYY-MM-DD±HH:MM`).
85 86 87 88 89 90 91 92
    pub date_seance: String,
    #[serde(rename = "idJO")]
    pub id_jo: Option<String>,
    #[serde(rename = "numSeanceJO")]
    pub num_seance_jo: Option<String>,
    pub quantieme: String,
}

93
#[derive(Debug, Deserialize)]
94 95
#[serde(deny_unknown_fields)]
pub struct InfosReunionsInternationale {
Emmanuel Raviart's avatar
Emmanuel Raviart committed
96
    #[serde(deserialize_with = "str_to_bool", rename = "estReunionInternationale")]
97 98 99 100
    pub est_reunion_internationale: bool,
    #[serde(rename = "informationsComplementaires")]
    pub informations_complementaires: Option<EmptyChoice>,
    #[serde(rename = "listePays")]
101
    pub liste_pays: Option<ListePays>,
102 103
}

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
graphql_object!(InfosReunionsInternationale: Context |&self| {
    field est_reunion_internationale(&executor) -> bool {
        self.est_reunion_internationale
    }

    field pays_refs() -> Vec<&str> {
        match &self.liste_pays {
            None => vec![],
            Some(ref liste_pays) => liste_pays.pays_ref
                .iter()
                .map(|ref pays_ref| pays_ref.as_str())
                .collect(),
        }
    }
});

120 121
#[derive(Clone, Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
122
pub struct LieuReunion {
123 124 125 126 127 128 129
    pub code: Option<String>,
    #[serde(rename = "libelleCourt")]
    pub libelle_court: Option<String>,
    #[serde(rename = "libelleLong")]
    pub libelle_long: Option<String>,
}

130
#[derive(Clone, Debug, Deserialize)]
131 132 133 134 135 136 137 138 139 140
#[serde(deny_unknown_fields)]
pub struct Odj {
    #[serde(rename = "convocationODJ")]
    pub convocation_odj: Option<UnstructuredPointsOdj>,
    #[serde(rename = "pointsODJ")]
    pub points_odj: Option<PointsOdj>,
    #[serde(rename = "resumeODJ")]
    pub resume_odj: Option<UnstructuredPointsOdj>,
}

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
graphql_object!(Odj: Context |&self| {
    field convocation_odj() -> Vec<&str> {
        match self.convocation_odj {
            None => vec![],
            Some(ref convocation_odj) => convocation_odj.items
                .iter()
                .map(|s| s.as_str())
                .collect()
        }
    }

    field points_odj() -> Vec<&PointOdj> {
        match self.points_odj {
            None => vec![],
            Some(ref points_odj) => points_odj.points_odj
Emmanuel Raviart's avatar
Emmanuel Raviart committed
156 157
                .iter()
                .collect()
158 159 160 161 162 163 164 165 166 167 168 169 170 171
        }
    }

    field resume_odj() -> Vec<&str> {
        match self.resume_odj {
            None => vec![],
            Some(ref resume_odj) => resume_odj.items
                .iter()
                .map(|s| s.as_str())
                .collect()
        }
    }
});

172
#[derive(Clone, Debug, Deserialize)]
173
#[serde(deny_unknown_fields)]
174
pub struct OrganeDemandeur {
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
    pub nom: String,
    #[serde(rename = "organeRef")]
    pub organe_ref: String,
}

#[derive(Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
pub struct ParticipantInterne {
    #[serde(rename = "acteurRef")]
    pub acteur_ref: String,
    pub presence: String,
}

#[derive(Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
pub struct Participants {
    #[serde(rename = "participantsInternes")]
    pub participants_internes: Option<ParticipantsInternes>,
    #[serde(rename = "personnesAuditionnees")]
    pub personnes_auditionnees: Option<PersonnesAuditionnees>,
}

#[derive(Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
pub struct ParticipantsInternes {
Emmanuel Raviart's avatar
Emmanuel Raviart committed
200
    #[serde(deserialize_with = "map_to_vec", rename = "participantInterne")]
201 202 203 204 205 206 207
    pub participants_internes: Vec<ParticipantInterne>,
}

#[derive(Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
pub struct PersonneAuditionnee {
    #[serde(rename = "dateNais")]
208
    // TODO: Date<FixedOffset> type is not able to deserialize dates (`YYYY-MM-DD`).
209 210 211 212 213 214 215 216
    pub date_nais: Option<String>,
    pub ident: Ident,
    pub uid: Uid,
}

#[derive(Debug, Deserialize, GraphQLObject)]
#[serde(deny_unknown_fields)]
pub struct PersonnesAuditionnees {
Emmanuel Raviart's avatar
Emmanuel Raviart committed
217
    #[serde(deserialize_with = "map_to_vec", rename = "personneAuditionnee")]
218 219 220
    pub personnes_auditionnees: Vec<PersonneAuditionnee>,
}

221
#[derive(Debug, Deserialize)]
222 223 224
#[serde(deny_unknown_fields)]
pub struct Reunion {
    #[serde(rename = "compteRenduRef")]
225
    pub compte_rendu_ref: Option<String>,
226
    #[serde(rename = "cycleDeVie")]
227
    pub cycle_de_vie: CycleDeVie,
Emmanuel Raviart's avatar
Emmanuel Raviart committed
228
    // TODO: Sometimes field `demandeur` exists instead of `demandeurs`, but it is always null.
229
    demandeur: Option<EmptyChoice>,
230
    pub demandeurs: Option<Demandeurs>,
231
    #[serde(rename = "formatReunion")]
232 233
    pub format_reunion: Option<String>,
    pub identifiants: Option<Identifiants>,
234
    #[serde(rename = "infosReunionsInternationale")]
235
    pub infos_reunions_internationale: Option<InfosReunionsInternationale>,
236
    pub lieu: Option<LieuReunion>,
237
    #[serde(rename = "ODJ")]
238
    pub odj: Option<Odj>,
239
    #[serde(rename = "organeReuniRef")]
240
    pub organe_reuni_ref: Option<String>,
241 242 243 244 245
    #[serde(
        default,
        deserialize_with = "str_to_option_bool",
        rename = "ouverturePresse"
    )]
246 247
    pub ouverture_presse: Option<bool>,
    pub participants: Option<Participants>,
248
    #[serde(rename = "sessionRef")]
249
    pub session_ref: Option<String>,
250
    #[serde(rename = "timeStampDebut")]
251
    pub timestamp_debut: DateTime<FixedOffset>,
252 253
    // TODO: Some timestamps end after 23:59:59. For example: `2017-10-10T24:00:00.000+02:00`.
    #[serde(rename = "timeStampFin")]
254
    // pub timestamp_fin: DateTime<FixedOffset>,
255 256
    pub timestamp_fin: Option<String>,
    #[serde(rename = "typeReunion")]
257 258
    pub type_reunion: Option<String>,
    pub uid: String,
259 260 261 262
    #[serde(rename = "@xmlns:xsi")]
    xml_xsi: Option<XmlNamespace>,
}

263 264 265 266
impl Reunion {
    pub fn organe_reuni<'a>(&self, context: &'a Context) -> Option<&'a Organe> {
        match self.organe_reuni_ref {
            None => None,
267
            Some(ref organe_reuni_ref) => context.get_organe_at_uid(organe_reuni_ref),
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
        }
    }
}

graphql_object!(Reunion: Context |&self| {
    field compte_rendu_ref() -> &Option<String> {
        &self.compte_rendu_ref
    }

    field cycle_de_vie() -> &CycleDeVie {
        &self.cycle_de_vie
    }

    field demandeurs() -> &Option<Demandeurs> {
        &self.demandeurs
    }

    field format_reunion() -> &Option<String> {
        &self.format_reunion
    }

    field identifiants() -> &Option<Identifiants> {
        &self.identifiants
    }

    field infos_reunions_internationale() -> &Option<InfosReunionsInternationale> {
        &self.infos_reunions_internationale
    }

297
    field lieu() -> &Option<LieuReunion> {
298 299 300 301 302 303 304 305 306 307
        &self.lieu
    }

    field odj() -> &Option<Odj> {
        &self.odj
    }

    field organe_reuni(&executor) -> Option<&Organe> {
        match self.organe_reuni_ref {
            None => None,
308
            Some(ref organe_reuni_ref) => executor.context().get_organe_at_uid(organe_reuni_ref),
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
        }
    }

    field organe_reuni_ref() -> &Option<String> {
        &self.organe_reuni_ref
    }

    field ouverture_presse() -> Option<bool> {
        self.ouverture_presse
    }

    field participants() -> &Option<Participants> {
        &self.participants
    }

    field session_ref() -> &Option<String> {
        &self.session_ref
    }

    field timestamp_debut() -> &DateTime<FixedOffset> {
        &self.timestamp_debut
    }

    field timestamp_fin() -> &Option<String> {
        &self.timestamp_fin
    }

    field type_reunion() -> &Option<String> {
        &self.type_reunion
    }

    field uid() -> &str {
        &self.uid
    }
});

345
#[derive(Debug, Deserialize)]
346 347 348 349 350 351
#[serde(deny_unknown_fields)]
pub struct Reunions {
    #[serde(rename = "reunion")]
    pub reunions: Vec<Reunion>,
}

352
#[derive(Clone, Debug, Deserialize)]
353 354 355 356 357
#[serde(deny_unknown_fields)]
pub struct UnstructuredPointsOdj {
    #[serde(deserialize_with = "str_to_vec", rename = "item")]
    pub items: Vec<String>,
}