1use crate::error::{Error, ErrorKind};
4use serde::{de, ser, Deserialize, Serialize};
5use std::{fmt, str::FromStr};
6
7#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
12pub enum Collection {
13 Crates,
15
16 Rust,
18}
19
20impl Collection {
21 pub fn all() -> &'static [Self] {
23 &[Collection::Crates, Collection::Rust]
24 }
25
26 pub fn as_str(&self) -> &str {
28 match self {
29 Collection::Crates => "crates",
30 Collection::Rust => "rust",
31 }
32 }
33}
34
35impl fmt::Display for Collection {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 write!(f, "{}", self.as_str())
38 }
39}
40
41impl FromStr for Collection {
42 type Err = Error;
43
44 fn from_str(s: &str) -> Result<Self, Error> {
45 Ok(match s {
46 "crates" => Collection::Crates,
47 "rust" => Collection::Rust,
48 other => fail!(ErrorKind::Parse, "invalid package type: {}", other),
49 })
50 }
51}
52
53impl<'de> Deserialize<'de> for Collection {
54 fn deserialize<D: de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
55 use de::Error;
56 let string = String::deserialize(deserializer)?;
57 string.parse().map_err(D::Error::custom)
58 }
59}
60
61impl Serialize for Collection {
62 fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
63 self.to_string().serialize(serializer)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::Collection;
70
71 #[test]
72 fn parse_crate() {
73 let crate_kind = "crates".parse::<Collection>().unwrap();
74 assert_eq!(Collection::Crates, crate_kind);
75 assert_eq!("crates", crate_kind.as_str());
76 }
77
78 #[test]
79 fn parse_rust() {
80 let rust_kind = "rust".parse::<Collection>().unwrap();
81 assert_eq!(Collection::Rust, rust_kind);
82 assert_eq!("rust", rust_kind.as_str());
83 }
84
85 #[test]
86 fn parse_other() {
87 assert!("foobar".parse::<Collection>().is_err());
88 }
89}