1use 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 User(UserId),
16 Team(TeamId),
18}
19
20#[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}