youtube_dl_parser/state/parsed_state/
mod.rs

1mod deleting_state;
2mod download_state;
3mod error_state;
4mod ffmpeg_state;
5mod youtube_state;
6
7pub use crate::state::parsed_state::deleting_state::DeletingState;
8pub use crate::state::parsed_state::download_state::DownloadState;
9pub use crate::state::parsed_state::error_state::ErrorState;
10pub use crate::state::parsed_state::ffmpeg_state::FFmpegState;
11pub use crate::state::parsed_state::youtube_state::YoutubeState;
12
13enum ParsedStateHeader {
14    YouTube,
15    Download,
16    FFmpeg,
17    Deleting,
18    Error,
19    Other(String),
20}
21
22/// General parsed state, can contain all of the more specific states
23pub enum ParsedState {
24    Youtube(YoutubeState),
25    Download(DownloadState),
26    FFMpeg(FFmpegState),
27    Error(ErrorState),
28    Deleting(DeletingState),
29    None(String),
30    Unknown(String),
31    ParseError(String),
32}
33
34impl ParsedState {
35    pub fn parse(output: String) -> Self {
36        let mut split = output.split(' ').filter(|string| !string.is_empty());
37        let Some(state_header)= split.next() else { return ParsedState::ParseError("Output is empty".to_owned()) };
38        let Some(state_header) = Self::parse_state_header(state_header) else { return ParsedState::None(output)};
39        match state_header {
40            ParsedStateHeader::YouTube => ParsedState::Youtube(YoutubeState::parse(split)),
41            ParsedStateHeader::Download => ParsedState::Download(DownloadState::parse(split)),
42            ParsedStateHeader::FFmpeg => ParsedState::FFMpeg(FFmpegState::parse(split)),
43            ParsedStateHeader::Deleting => ParsedState::Deleting(DeletingState::parse(split)),
44            ParsedStateHeader::Error => ParsedState::Error(ErrorState::parse(split)),
45            ParsedStateHeader::Other(_) => ParsedState::Unknown(output),
46        }
47    }
48
49    // Parse header
50    fn parse_state_header(state_header: &str) -> Option<ParsedStateHeader> {
51        let mut chars = state_header.chars();
52        let first_char = chars.next()?;
53        let last_char = chars.next_back()?;
54        if first_char == '[' && last_char == ']' {
55            let mode = chars.as_str();
56            match mode {
57                "youtube" => Some(ParsedStateHeader::YouTube),
58                "download" => Some(ParsedStateHeader::Download),
59                "ffmpeg" => Some(ParsedStateHeader::FFmpeg),
60                _ => Some(ParsedStateHeader::Other(mode.to_owned())),
61            }
62        } else if state_header == "ERROR:" {
63            Some(ParsedStateHeader::Error)
64        } else if state_header == "Deleting" {
65            Some(ParsedStateHeader::Deleting)
66        } else {
67            None
68        }
69    }
70}