1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::str::FromStr;
4use uuid::Uuid;
5
6use crate::errors::ThothError;
7#[cfg(feature = "backend")]
8use crate::schema::contribution;
9
10#[cfg_attr(feature = "backend", derive(DbEnum, juniper::GraphQLEnum))]
11#[cfg_attr(feature = "backend", DieselType = "Contribution_type")]
12#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
13#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
14pub enum ContributionType {
15 Author,
16 Editor,
17 Translator,
18 Photographer,
19 Ilustrator,
20 #[cfg_attr(feature = "backend", db_rename = "music-editor")]
21 MusicEditor,
22 #[cfg_attr(feature = "backend", db_rename = "foreword-by")]
23 ForewordBy,
24 #[cfg_attr(feature = "backend", db_rename = "introduction-by")]
25 IntroductionBy,
26 #[cfg_attr(feature = "backend", db_rename = "afterword-by")]
27 AfterwordBy,
28 #[cfg_attr(feature = "backend", db_rename = "preface-by")]
29 PrefaceBy,
30}
31
32#[cfg_attr(feature = "backend", derive(Queryable))]
33pub struct Contribution {
34 pub work_id: Uuid,
35 pub contributor_id: Uuid,
36 pub contribution_type: ContributionType,
37 pub main_contribution: bool,
38 pub biography: Option<String>,
39 pub institution: Option<String>,
40}
41
42#[cfg_attr(
43 feature = "backend",
44 derive(juniper::GraphQLInputObject, Insertable),
45 table_name = "contribution"
46)]
47pub struct NewContribution {
48 pub work_id: Uuid,
49 pub contributor_id: Uuid,
50 pub contribution_type: ContributionType,
51 pub main_contribution: bool,
52 pub biography: Option<String>,
53 pub institution: Option<String>,
54}
55
56#[cfg_attr(
57 feature = "backend",
58 derive(juniper::GraphQLInputObject, AsChangeset),
59 changeset_options(treat_none_as_null = "true"),
60 table_name = "contribution"
61)]
62pub struct PatchContribution {
63 pub work_id: Uuid,
64 pub contributor_id: Uuid,
65 pub contribution_type: ContributionType,
66 pub main_contribution: bool,
67 pub biography: Option<String>,
68 pub institution: Option<String>,
69}
70
71impl Default for ContributionType {
72 fn default() -> ContributionType {
73 ContributionType::Author
74 }
75}
76
77impl fmt::Display for ContributionType {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 match self {
80 ContributionType::Author => write!(f, "Author"),
81 ContributionType::Editor => write!(f, "Editor"),
82 ContributionType::Translator => write!(f, "Translator"),
83 ContributionType::Photographer => write!(f, "Photographer"),
84 ContributionType::Ilustrator => write!(f, "Ilustrator"),
85 ContributionType::MusicEditor => write!(f, "Music Editor"),
86 ContributionType::ForewordBy => write!(f, "Foreword By"),
87 ContributionType::IntroductionBy => write!(f, "Introduction By"),
88 ContributionType::AfterwordBy => write!(f, "Afterword By"),
89 ContributionType::PrefaceBy => write!(f, "Preface By"),
90 }
91 }
92}
93
94impl FromStr for ContributionType {
95 type Err = ThothError;
96
97 fn from_str(input: &str) -> Result<ContributionType, ThothError> {
98 match input {
99 "Author" => Ok(ContributionType::Author),
100 "Editor" => Ok(ContributionType::Editor),
101 "Translator" => Ok(ContributionType::Translator),
102 "Photographer" => Ok(ContributionType::Photographer),
103 "Ilustrator" => Ok(ContributionType::Ilustrator),
104 "Music Editor" => Ok(ContributionType::MusicEditor),
105 "Foreword By" => Ok(ContributionType::ForewordBy),
106 "Introduction By" => Ok(ContributionType::IntroductionBy),
107 "Afterword By" => Ok(ContributionType::AfterwordBy),
108 "Preface By" => Ok(ContributionType::PrefaceBy),
109 _ => Err(ThothError::InvalidContributionType(input.to_string())),
110 }
111 }
112}
113
114#[test]
115fn test_contributiontype_default() {
116 let contributiontype: ContributionType = Default::default();
117 assert_eq!(contributiontype, ContributionType::Author);
118}
119
120#[test]
121fn test_contributiontype_display() {
122 assert_eq!(format!("{}", ContributionType::Author), "Author");
123 assert_eq!(format!("{}", ContributionType::Editor), "Editor");
124 assert_eq!(format!("{}", ContributionType::Translator), "Translator");
125 assert_eq!(
126 format!("{}", ContributionType::Photographer),
127 "Photographer"
128 );
129 assert_eq!(format!("{}", ContributionType::Ilustrator), "Ilustrator");
130 assert_eq!(format!("{}", ContributionType::MusicEditor), "Music Editor");
131 assert_eq!(format!("{}", ContributionType::ForewordBy), "Foreword By");
132 assert_eq!(
133 format!("{}", ContributionType::IntroductionBy),
134 "Introduction By"
135 );
136 assert_eq!(format!("{}", ContributionType::AfterwordBy), "Afterword By");
137 assert_eq!(format!("{}", ContributionType::PrefaceBy), "Preface By");
138}
139
140#[test]
141fn test_contributiontype_fromstr() {
142 assert_eq!(
143 ContributionType::from_str("Author").unwrap(),
144 ContributionType::Author
145 );
146 assert_eq!(
147 ContributionType::from_str("Editor").unwrap(),
148 ContributionType::Editor
149 );
150 assert_eq!(
151 ContributionType::from_str("Translator").unwrap(),
152 ContributionType::Translator
153 );
154 assert_eq!(
155 ContributionType::from_str("Photographer").unwrap(),
156 ContributionType::Photographer
157 );
158 assert_eq!(
159 ContributionType::from_str("Ilustrator").unwrap(),
160 ContributionType::Ilustrator
161 );
162 assert_eq!(
163 ContributionType::from_str("Music Editor").unwrap(),
164 ContributionType::MusicEditor
165 );
166 assert_eq!(
167 ContributionType::from_str("Foreword By").unwrap(),
168 ContributionType::ForewordBy
169 );
170 assert_eq!(
171 ContributionType::from_str("Introduction By").unwrap(),
172 ContributionType::IntroductionBy
173 );
174 assert_eq!(
175 ContributionType::from_str("Afterword By").unwrap(),
176 ContributionType::AfterwordBy
177 );
178 assert_eq!(
179 ContributionType::from_str("Preface By").unwrap(),
180 ContributionType::PrefaceBy
181 );
182
183 assert!(ContributionType::from_str("Juggler").is_err());
184 assert!(ContributionType::from_str("Supervisor").is_err());
185}