@@ -7,30 +7,6 @@ use content_inspector::{self, ContentType};
77use crate::errors::*;
88
99const THEME_PREVIEW_FILE: &[u8] = include_bytes!("../assets/theme_preview.rs");
10−#[derive(Debug, Clone, PartialEq)]
11−pub struct OrdinaryFile {
12− path: OsString,
13− user_provided_path: Option<OsString>,
14−}
15−
16−impl OrdinaryFile {
17− pub fn from_path(path: &OsStr) -> OrdinaryFile {
18− OrdinaryFile {
19− path: path.to_os_string(),
20− user_provided_path: None,
21− }
22− }
23−
24− pub fn set_provided_path(&mut self, user_provided_path: &OsStr) {
25− self.user_provided_path = Some(user_provided_path.to_os_string());
26− }
27−
28− pub(crate) fn provided_path<'a>(&'a self) -> &'a OsStr {
29− self.user_provided_path
30− .as_ref()
31− .unwrap_or_else(|| &self.path)
32− }
33−}
3410
3511#[derive(Debug, Clone)]
3612pub struct InputDescription {
@@ -39,69 +15,134 @@ pub struct InputDescription {
3915 pub name: String,
4016}
4117
42−pub enum Input {
43− StdIn(Option<OsString>),
44− Ordinary(OrdinaryFile),
45− FromReader(Box<dyn Read>, Option<OsString>),
18+pub enum InputKind {
19+ OrdinaryFile(OsString),
20+ StdIn,
4621 ThemePreviewFile,
22+ CustomReader(Box<dyn BufRead>),
23+}
24+
25+#[derive(Clone, Default)]
26+pub struct InputMetadata {
27+ pub user_provided_name: Option<OsString>,
28+}
29+
30+pub struct Input {
31+ pub kind: InputKind,
32+ pub metadata: InputMetadata,
33+}
34+
35+pub enum OpenedInputKind {
36+ OrdinaryFile(OsString),
37+ StdIn,
38+ ThemePreviewFile,
39+ CustomReader,
40+}
41+
42+pub struct OpenedInput<'a> {
43+ pub kind: OpenedInputKind,
44+ pub metadata: InputMetadata,
45+ pub reader: InputReader<'a>,
4746}
4847
4948impl Input {
50− pub(crate) fn get_reader<'a, R: BufRead + 'a>(&self, stdin: R) -> Result<InputReader<'a>> {
51− match self {
52− Input::StdIn(_) => Ok(InputReader::new(stdin)),
53− Input::Ordinary(ofile) => {
54− let file = File::open(&ofile.path)
55− .map_err(|e| format!("'{}': {}", ofile.path.to_string_lossy(), e))?;
56−
57− if file.metadata()?.is_dir() {
58− return Err(
59− format!("'{}' is a directory.", ofile.path.to_string_lossy()).into(),
60− );
61− }
62−
63− Ok(InputReader::new(BufReader::new(file)))
64− }
65− Input::ThemePreviewFile => Ok(InputReader::new(THEME_PREVIEW_FILE)),
66− Input::FromReader(_, _) => unimplemented!(), //Ok(InputReader::new(BufReader::new(reader))),
49+ pub fn ordinary_file(path: &OsStr) -> Self {
50+ Input {
51+ kind: InputKind::OrdinaryFile(path.to_os_string()),
52+ metadata: InputMetadata::default(),
6753 }
6854 }
6955
70− pub(crate) fn description(&self) -> InputDescription {
71− match self {
72− Input::Ordinary(ofile) => InputDescription {
73− full: format!("file '{}'", &ofile.provided_path().to_string_lossy()),
74− prefix: "File: ".to_owned(),
75− name: ofile.provided_path().to_string_lossy().into_owned(),
76− },
77− Input::StdIn(Some(name)) => InputDescription {
78− full: format!(
79− "STDIN (with name '{}')",
80− name.to_string_lossy().into_owned()
81− ),
82− prefix: "File: ".to_owned(),
83− name: name.to_string_lossy().into_owned(),
84− },
85− Input::StdIn(None) => InputDescription {
86− full: "STDIN".to_owned(),
87− prefix: "".to_owned(),
88− name: "STDIN".to_owned(),
89− },
90− Input::ThemePreviewFile => InputDescription {
91− full: "".to_owned(),
92− prefix: "".to_owned(),
93− name: "".to_owned(),
94− },
95− Input::FromReader(_, Some(name)) => InputDescription {
56+ pub fn stdin() -> Self {
57+ Input {
58+ kind: InputKind::StdIn,
59+ metadata: InputMetadata::default(),
60+ }
61+ }
62+
63+ pub fn theme_preview_file() -> Self {
64+ Input {
65+ kind: InputKind::ThemePreviewFile,
66+ metadata: InputMetadata::default(),
67+ }
68+ }
69+
70+ pub fn is_stdin(&self) -> bool {
71+ if let InputKind::StdIn = self.kind {
72+ true
73+ } else {
74+ false
75+ }
76+ }
77+
78+ pub fn set_provided_name(&mut self, provided_name: Option<&OsStr>) {
79+ self.metadata.user_provided_name = provided_name.map(|n| n.to_owned());
80+ }
81+
82+ pub fn open<'a, R: BufRead + 'a>(self, stdin: R) -> Result<OpenedInput<'a>> {
83+ match self.kind {
84+ InputKind::StdIn => Ok(OpenedInput {
85+ kind: OpenedInputKind::StdIn,
86+ metadata: self.metadata,
87+ reader: InputReader::new(stdin),
88+ }),
89+ InputKind::OrdinaryFile(path) => Ok(OpenedInput {
90+ kind: OpenedInputKind::OrdinaryFile(path.clone()),
91+ metadata: self.metadata,
92+ reader: {
93+ let file = File::open(&path)
94+ .map_err(|e| format!("'{}': {}", path.to_string_lossy(), e))?;
95+ if file.metadata()?.is_dir() {
96+ return Err(format!("'{}' is a directory.", path.to_string_lossy()).into());
97+ }
98+ InputReader::new(BufReader::new(file))
99+ },
100+ }),
101+ InputKind::ThemePreviewFile => Ok(OpenedInput {
102+ kind: OpenedInputKind::ThemePreviewFile,
103+ metadata: self.metadata,
104+ reader: InputReader::new(THEME_PREVIEW_FILE),
105+ }),
106+ InputKind::CustomReader(reader) => Ok(OpenedInput {
107+ kind: OpenedInputKind::CustomReader,
108+ metadata: self.metadata,
109+ reader: InputReader::new(BufReader::new(reader)),
110+ }),
111+ }
112+ }
113+}
114+
115+impl<'a> OpenedInput<'a> {
116+ pub fn description(&self) -> InputDescription {
117+ if let Some(ref name) = self.metadata.user_provided_name {
118+ InputDescription {
96119 full: format!("file '{}'", name.to_string_lossy()),
97120 prefix: "File: ".to_owned(),
98121 name: name.to_string_lossy().into_owned(),
99− },
100− Input::FromReader(_, None) => InputDescription {
101− full: "reader".to_owned(),
102− prefix: "".to_owned(),
103− name: "READER".into(),
104− },
122+ }
123+ } else {
124+ match self.kind {
125+ OpenedInputKind::OrdinaryFile(ref path) => InputDescription {
126+ full: format!("file '{}'", path.to_string_lossy()),
127+ prefix: "File: ".to_owned(),
128+ name: path.to_string_lossy().into_owned(),
129+ },
130+ OpenedInputKind::StdIn => InputDescription {
131+ full: "STDIN".to_owned(),
132+ prefix: "".to_owned(),
133+ name: "STDIN".to_owned(),
134+ },
135+ OpenedInputKind::ThemePreviewFile => InputDescription {
136+ full: "".to_owned(),
137+ prefix: "".to_owned(),
138+ name: "".to_owned(),
139+ },
140+ OpenedInputKind::CustomReader => InputDescription {
141+ full: "reader".to_owned(),
142+ prefix: "".to_owned(),
143+ name: "READER".into(),
144+ },
145+ }
105146 }
106147 }
107148}