diff options
-rw-r--r-- | librepology/src/v1/buffer.rs | 41 | ||||
-rw-r--r-- | librepology/src/v1/mod.rs | 2 | ||||
-rw-r--r-- | librepology/src/v1/stdinapi.rs | 62 | ||||
-rw-r--r-- | src/backend.rs | 14 |
4 files changed, 49 insertions, 70 deletions
diff --git a/librepology/src/v1/buffer.rs b/librepology/src/v1/buffer.rs new file mode 100644 index 0000000..534ab4c --- /dev/null +++ b/librepology/src/v1/buffer.rs @@ -0,0 +1,41 @@ +use std::io::Read; + +use crate::v1::error::Result; +use crate::v1::error::RepologyError as Error; +use crate::v1::types::Problem; +use crate::v1::types::Package; +use crate::v1::api::Api; + +#[derive(Debug)] +pub struct BufferApi { + buf: String, +} + +impl BufferApi +{ + pub fn read_from<R>(mut input: R) -> Result<BufferApi> + where R: Read, + { + let mut buf = String::new(); + let read = input.read_to_string(&mut buf)?; + trace!("Read {} bytes from stdin", read); + Ok(BufferApi { buf }) + } +} + +impl Api for BufferApi { + + fn project<N: AsRef<str>>(&self, _name: N) -> Result<Vec<Package>> { + serde_json::de::from_str(&self.buf).map_err(Error::from) + } + + fn problems_for_repo<R: AsRef<str>>(&self, _repo: R) -> Result<Vec<Problem>> { + serde_json::de::from_str(&self.buf).map_err(Error::from) + } + + fn problems_for_maintainer<M: AsRef<str>>(&self, _maintainer: M) -> Result<Vec<Problem>> { + serde_json::de::from_str(&self.buf).map_err(Error::from) + } + +} + diff --git a/librepology/src/v1/mod.rs b/librepology/src/v1/mod.rs index 1d1db8d..aa1cd9b 100644 --- a/librepology/src/v1/mod.rs +++ b/librepology/src/v1/mod.rs @@ -1,5 +1,5 @@ pub mod restapi; -pub mod stdinapi; +pub mod buffer; pub mod api; pub mod types; pub mod error; diff --git a/librepology/src/v1/stdinapi.rs b/librepology/src/v1/stdinapi.rs deleted file mode 100644 index 6c0d38b..0000000 --- a/librepology/src/v1/stdinapi.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::io::{Stdin, Read}; -use std::cell::RefCell; -use std::ops::Deref; -use std::ops::DerefMut; - -use crate::v1::error::Result; -use crate::v1::error::RepologyError as Error; -use crate::v1::types::Problem; -use crate::v1::types::Package; -use crate::v1::api::Api; - -/// Wrapper for "stdin" -/// -/// This way we can implement the `Api` trait for StdIn (via a Wrapper for interior mutability) -/// This way we can read the data from stdin and process it. -pub struct StdinWrapper(RefCell<Stdin>); - -impl From<Stdin> for StdinWrapper { - fn from(inner: Stdin) -> Self { - StdinWrapper(RefCell::new(inner)) - } -} - -impl Deref for StdinWrapper { - type Target = RefCell<Stdin>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for StdinWrapper { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -impl Api for StdinWrapper { - - fn project<N: AsRef<str>>(&self, _name: N) -> Result<Vec<Package>> { - let s = read_to_string(self.0.try_borrow_mut()?.deref_mut())?; - serde_json::de::from_str(&s).map_err(Error::from) - } - - fn problems_for_repo<R: AsRef<str>>(&self, _repo: R) -> Result<Vec<Problem>> { - let s = read_to_string(self.0.try_borrow_mut()?.deref_mut())?; - serde_json::de::from_str(&s).map_err(Error::from) - } - - fn problems_for_maintainer<M: AsRef<str>>(&self, _maintainer: M) -> Result<Vec<Problem>> { - let s = read_to_string(self.0.try_borrow_mut()?.deref_mut())?; - serde_json::de::from_str(&s).map_err(Error::from) - } - -} - -fn read_to_string(input: &mut dyn Read) -> Result<String> { - let mut buffer = String::new(); - let read = input.read_to_string(&mut buffer)?; - trace!("Read {} bytes from stdin", read); - Ok(buffer) -} diff --git a/src/backend.rs b/src/backend.rs index efc6f37..feba9d9 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3,7 +3,7 @@ use clap::ArgMatches; use librepology::v1::api::Api; use librepology::v1::error::Result; use librepology::v1::restapi::RestApi; -use librepology::v1::stdinapi::StdinWrapper; +use librepology::v1::buffer::BufferApi; use librepology::v1::types::*; use crate::config::Configuration; @@ -11,7 +11,7 @@ use crate::config::Configuration; /// Helper type for cli implementation /// for being transparent in what backend we use pub enum Backend { - Stdin(StdinWrapper), + Buffer(BufferApi), RepologyOrg(RestApi), } @@ -21,30 +21,30 @@ pub enum Backend { impl Api for Backend { fn project<N: AsRef<str>>(&self, name: N) -> Result<Vec<Package>> { match self { - Backend::Stdin(inner) => inner.project(name), + Backend::Buffer(inner) => inner.project(name), Backend::RepologyOrg(inner) => inner.project(name), } } fn problems_for_repo<R: AsRef<str>>(&self, repo: R) -> Result<Vec<Problem>> { match self { - Backend::Stdin(inner) => inner.problems_for_repo(repo), + Backend::Buffer(inner) => inner.problems_for_repo(repo), Backend::RepologyOrg(inner) => inner.problems_for_repo(repo), } } fn problems_for_maintainer<M: AsRef<str>>(&self, maintainer: M) -> Result<Vec<Problem>> { match self { - Backend::Stdin(inner) => inner.problems_for_maintainer(maintainer), + Backend::Buffer(inner) => inner.problems_for_maintainer(maintainer), Backend::RepologyOrg(inner) => inner.problems_for_maintainer(maintainer), } } } -pub fn new_backend(app: &ArgMatches, config: &Configuration) -> Result<Backend> { +pub fn new_backend(app: &ArgMatches, config: &Configuration) -> anyhow::Result<Backend> { if app.is_present("input_stdin") { trace!("Building new STDIN backend"); - Ok(Backend::Stdin(StdinWrapper::from(::std::io::stdin()))) + BufferApi::read_from(std::io::stdin()).map(Backend::Buffer).map_err(anyhow::Error::from) } else { trace!("Building new remote backend"); let url = config.repology_url().as_str().into(); |