db_dump/
crate_owners.rs

1//! <b style="font-variant:small-caps">crate_owners.csv</b>
2
3use crate::crates::CrateId;
4use crate::error::{err, Result};
5use crate::load::FromRecord;
6use crate::teams::TeamId;
7use crate::users::UserId;
8use chrono::{DateTime, Utc};
9use csv::StringRecord;
10use serde_derive::Deserialize;
11
12#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
13pub enum OwnerId {
14    /// owner_kind=0
15    User(UserId),
16    /// owner_kind=1
17    Team(TeamId),
18}
19
20/// One row of **crate_owners.csv**.
21#[derive(Clone, Debug)]
22#[non_exhaustive]
23pub struct Row {
24    pub crate_id: CrateId,
25    pub owner_id: OwnerId,
26    pub created_at: DateTime<Utc>,
27    pub created_by: Option<UserId>,
28}
29
30impl FromRecord for Row {
31    fn from_record(record: &StringRecord, headers: &StringRecord) -> Result<Self> {
32        de(record, headers)
33    }
34}
35
36fn de(record: &StringRecord, headers: &StringRecord) -> Result<Row> {
37    #[derive(Deserialize)]
38    #[serde(deny_unknown_fields)]
39    struct Record {
40        crate_id: CrateId,
41        #[serde(deserialize_with = "crate::datetime::de")]
42        created_at: DateTime<Utc>,
43        created_by: Option<UserId>,
44        owner_id: u32,
45        owner_kind: u8,
46    }
47
48    let record: Record = record.deserialize(Some(headers)).map_err(err)?;
49
50    let owner_id = match record.owner_kind {
51        0 => OwnerId::User(UserId(record.owner_id)),
52        1 => OwnerId::Team(TeamId(record.owner_id)),
53        other => {
54            return Err(err(format_args!(
55                "unrecognized crate_owners.csv owner_kind: {}",
56                other,
57            )))
58        }
59    };
60
61    Ok(Row {
62        crate_id: record.crate_id,
63        created_at: record.created_at,
64        created_by: record.created_by,
65        owner_id,
66    })
67}
68
69impl PartialEq<UserId> for OwnerId {
70    fn eq(&self, other: &UserId) -> bool {
71        match self {
72            OwnerId::User(user_id) => user_id == other,
73            OwnerId::Team(_) => false,
74        }
75    }
76}
77
78impl PartialEq<TeamId> for OwnerId {
79    fn eq(&self, other: &TeamId) -> bool {
80        match self {
81            OwnerId::User(_) => false,
82            OwnerId::Team(team_id) => team_id == other,
83        }
84    }
85}
86
87impl PartialEq<OwnerId> for UserId {
88    fn eq(&self, other: &OwnerId) -> bool {
89        other == self
90    }
91}
92
93impl PartialEq<OwnerId> for TeamId {
94    fn eq(&self, other: &OwnerId) -> bool {
95        other == self
96    }
97}