rust_anilist/models/
source.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2022-2025 Andriel Ferreira <https://github.com/AndrielFR>
3
4//! This module contains the `Source` enum.
5
6use serde::{Deserialize, Serialize};
7
8/// Represents the source of a media.
9#[derive(Debug, Default, Clone, Eq, Hash, PartialEq, Deserialize, Serialize)]
10#[serde(rename_all(deserialize = "SCREAMING_SNAKE_CASE"))]
11pub enum Source {
12    /// The original source.
13    Original,
14    /// Manga source.
15    Manga,
16    /// Light novel source.
17    LightNovel,
18    /// Visual novel source.
19    VisualNovel,
20    /// Video game source.
21    VideoGame,
22    /// Other source.
23    #[default]
24    Other,
25    /// Novel source.
26    Novel,
27    /// Doujinshi source.
28    Doujinshi,
29    /// Anime source.
30    Anime,
31    /// Web novel source.
32    WebNovel,
33    /// Live action source.
34    LiveAction,
35    /// Game source.
36    Game,
37    /// Comic source.
38    Comic,
39    /// Multimedia project source.
40    MultimediaProject,
41    /// Picture book source.
42    PictureBook,
43}
44
45impl Source {
46    /// Returns a summary of the source.
47    pub fn summary(&self) -> &str {
48        match self {
49            Source::Original => "An original production not based of another work",
50            Source::Manga => "Asian comic book",
51            Source::LightNovel => {
52                "A written work published in volumes primarily targeting young adults and teens"
53            }
54            Source::VisualNovel => {
55                "A video game genre that originated in Japan, featuring mostly static graphics"
56            }
57            Source::VideoGame => {
58                "An electronic game that involves interaction with a user interface"
59            }
60            Source::Other => "A source that does not fit any other category",
61            Source::Novel => "A written work not published in volumes",
62            Source::Doujinshi => "Self-published works",
63            Source::Anime => "Japanese animated productions",
64            Source::WebNovel => "A novel published online",
65            Source::LiveAction => {
66                "A work that involves live action rather than animation such as movies or TV shows"
67            }
68            Source::Game => "A competitive activity or sport excluding video games",
69            Source::Comic => "A publication that consists of comic art in the form of sequential panels excluding manga",
70            Source::MultimediaProject => "A work that is a collection of multiple media",
71            Source::PictureBook => "A book with pictures and little text",
72        }
73    }
74}
75
76impl From<&str> for Source {
77    fn from(source: &str) -> Self {
78        match source.to_ascii_uppercase().as_str() {
79            "ORIGINAL" => Source::Original,
80            "MANGA" => Source::Manga,
81            "LIGHT_NOVEL" => Source::LightNovel,
82            "VISUAL_NOVEL" => Source::VisualNovel,
83            "VIDEO_GAME" => Source::VideoGame,
84            "OTHER" => Source::Other,
85            "NOVEL" => Source::Novel,
86            "DOUJINSHI" => Source::Doujinshi,
87            "ANIME" => Source::Anime,
88            "WEB_NOVEL" => Source::WebNovel,
89            "LIVE_ACTION" => Source::LiveAction,
90            "GAME" => Source::Game,
91            "COMIC" => Source::Comic,
92            "MULTIMEDIA_PROJECT" => Source::MultimediaProject,
93            "PICTURE_BOOK" => Source::PictureBook,
94            _ => Source::Other,
95        }
96    }
97}
98
99impl From<String> for Source {
100    fn from(source: String) -> Self {
101        Source::from(source.as_str())
102    }
103}
104
105impl std::fmt::Display for Source {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        match self {
108            Source::Original => write!(f, "Original"),
109            Source::Manga => write!(f, "Manga"),
110            Source::LightNovel => write!(f, "Light Novel"),
111            Source::VisualNovel => write!(f, "Visual Novel"),
112            Source::VideoGame => write!(f, "Video Game"),
113            Source::Other => write!(f, "Other"),
114            Source::Novel => write!(f, "Novel"),
115            Source::Doujinshi => write!(f, "Doujinshi"),
116            Source::Anime => write!(f, "Anime"),
117            Source::WebNovel => write!(f, "Web Novel"),
118            Source::LiveAction => write!(f, "Live Action"),
119            Source::Game => write!(f, "Game"),
120            Source::Comic => write!(f, "Comic"),
121            Source::MultimediaProject => write!(f, "Multimedia Project"),
122            Source::PictureBook => write!(f, "Picture Book"),
123        }
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn test_from_str() {
133        assert_eq!(Source::from("original"), Source::Original);
134        assert_eq!(Source::from("MANGA"), Source::Manga);
135        assert_eq!(Source::from("light_novel"), Source::LightNovel);
136        assert_eq!(Source::from("VISUAL_NOVEL"), Source::VisualNovel);
137        assert_eq!(Source::from("video_game"), Source::VideoGame);
138        assert_eq!(Source::from("other"), Source::Other);
139        assert_eq!(Source::from("NOVEL"), Source::Novel);
140        assert_eq!(Source::from("doujinshi"), Source::Doujinshi);
141        assert_eq!(Source::from("ANIME"), Source::Anime);
142        assert_eq!(Source::from("web_novel"), Source::WebNovel);
143        assert_eq!(Source::from("LIVE_ACTION"), Source::LiveAction);
144        assert_eq!(Source::from("game"), Source::Game);
145        assert_eq!(Source::from("COMIC"), Source::Comic);
146        assert_eq!(
147            Source::from("multimedia_project"),
148            Source::MultimediaProject
149        );
150        assert_eq!(Source::from("picture_book"), Source::PictureBook);
151        assert_eq!(Source::from("unknown"), Source::Other); // Default case
152    }
153
154    #[test]
155    fn test_from_string() {
156        assert_eq!(Source::from("original".to_string()), Source::Original);
157        assert_eq!(Source::from("MANGA".to_string()), Source::Manga);
158        assert_eq!(Source::from("light_novel".to_string()), Source::LightNovel);
159        assert_eq!(
160            Source::from("VISUAL_NOVEL".to_string()),
161            Source::VisualNovel
162        );
163        assert_eq!(Source::from("video_game".to_string()), Source::VideoGame);
164        assert_eq!(Source::from("other".to_string()), Source::Other);
165        assert_eq!(Source::from("NOVEL".to_string()), Source::Novel);
166        assert_eq!(Source::from("doujinshi".to_string()), Source::Doujinshi);
167        assert_eq!(Source::from("ANIME".to_string()), Source::Anime);
168        assert_eq!(Source::from("web_novel".to_string()), Source::WebNovel);
169        assert_eq!(Source::from("LIVE_ACTION".to_string()), Source::LiveAction);
170        assert_eq!(Source::from("game".to_string()), Source::Game);
171        assert_eq!(Source::from("COMIC".to_string()), Source::Comic);
172        assert_eq!(
173            Source::from("multimedia_project".to_string()),
174            Source::MultimediaProject
175        );
176        assert_eq!(
177            Source::from("picture_book".to_string()),
178            Source::PictureBook
179        );
180        assert_eq!(Source::from("unknown".to_string()), Source::Other); // Default case
181    }
182}