[librsvg/rustify-rsvg-convert] rsvg-convert: simplify input handling



commit c9171011567a74a6bfbf137c51ddded77ef6b09f
Author: Paolo Borelli <pborelli gnome org>
Date:   Sat Jan 9 14:24:25 2021 +0100

    rsvg-convert: simplify input handling
    
    Remove the custom iterator and simply iterate the list of inputs
    and open the corresponding stream as we go. This is way less code
    and allows us to detect and handle errors when opening a file.

 src/bin/rsvg-convert/cli.rs   | 10 ++---
 src/bin/rsvg-convert/input.rs | 89 ++++---------------------------------------
 src/bin/rsvg-convert/main.rs  | 21 +++++++++-
 3 files changed, 30 insertions(+), 90 deletions(-)
---
diff --git a/src/bin/rsvg-convert/cli.rs b/src/bin/rsvg-convert/cli.rs
index d6a01d42..69d5aac3 100644
--- a/src/bin/rsvg-convert/cli.rs
+++ b/src/bin/rsvg-convert/cli.rs
@@ -32,7 +32,7 @@ pub struct Args {
     pub unlimited: bool,
     pub keep_image_data: bool,
     output: Option<PathBuf>,
-    input: Vec<PathBuf>,
+    pub input: Vec<Input>,
 }
 
 impl Args {
@@ -225,8 +225,8 @@ impl Args {
             keep_image_data,
             output: matches.value_of_os("output").map(PathBuf::from),
             input: match matches.values_of_os("FILE") {
-                Some(values) => values.map(PathBuf::from).collect(),
-                None => Vec::new(),
+                Some(values) => values.map(PathBuf::from).map(Input::Path).collect(),
+                None => vec![Input::Stdin],
             },
         };
 
@@ -252,10 +252,6 @@ impl Args {
     pub fn output(&self) -> Option<&Path> {
         self.output.as_deref()
     }
-
-    pub fn input(&self) -> Input<'_> {
-        Input::new(&self.input)
-    }
 }
 
 fn is_valid_resolution(v: String) -> Result<(), String> {
diff --git a/src/bin/rsvg-convert/input.rs b/src/bin/rsvg-convert/input.rs
index 5f01a9d2..6290753c 100644
--- a/src/bin/rsvg-convert/input.rs
+++ b/src/bin/rsvg-convert/input.rs
@@ -1,90 +1,17 @@
 // input file handling for rsvg-convert
-
-use core::ops::Deref;
-use gio::FileExt;
-use std::fmt;
 use std::path::PathBuf;
 
-struct Stdin;
-
-impl Stdin {
-    pub fn stream() -> gio::UnixInputStream {
-        unsafe { gio::UnixInputStream::new(0) }
-    }
-}
-
-pub enum Input<'a> {
-    Paths(std::slice::Iter<'a, PathBuf>),
-    Stdin(std::iter::Once<gio::UnixInputStream>),
-}
-
-impl<'a> Input<'a> {
-    pub fn new(paths: &'a [PathBuf]) -> Self {
-        match paths.len() {
-            0 => Input::Stdin(std::iter::once(Stdin::stream())),
-            _ => Input::Paths(paths.iter()),
-        }
-    }
-}
-
-enum Stream {
-    File(gio::FileInputStream),
-    Unix(gio::UnixInputStream),
-}
-
-impl Deref for Stream {
-    type Target = gio::InputStream;
-
-    fn deref(&self) -> &Self::Target {
-        match self {
-            Self::File(stream) => stream.as_ref(),
-            Self::Unix(stream) => stream.as_ref(),
-        }
-    }
-}
-
-pub struct Item {
-    stream: Stream,
-    file: Option<gio::File>,
+#[derive(Clone, Debug)]
+pub enum Input {
+    Stdin,
+    Path(PathBuf),
 }
 
-impl Item {
-    pub fn stream(&self) -> &gio::InputStream {
-        self.stream.deref()
-    }
-
-    pub fn file(&self) -> Option<&gio::File> {
-        self.file.as_ref()
-    }
-}
-
-impl fmt::Display for Item {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match &self.file {
-            Some(file) => file.get_path().unwrap().display().fmt(f),
-            None => "stdin".fmt(f),
-        }
-    }
-}
-
-impl Iterator for Input<'_> {
-    type Item = Item;
-
-    fn next(&mut self) -> Option<Self::Item> {
+impl std::fmt::Display for Input {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
-            Input::Paths(paths) => paths.next().and_then(|p| {
-                let file = gio::File::new_for_path(p);
-                let stream = file.read(None::<&gio::Cancellable>).ok()?;
-                Some(Item {
-                    stream: Stream::File(stream),
-                    file: Some(file),
-                })
-            }),
-
-            Input::Stdin(iter) => iter.next().map(|s| Item {
-                stream: Stream::Unix(s),
-                file: None,
-            }),
+            Input::Stdin => "stdin".fmt(f),
+            Input::Path(p) => p.display().fmt(f),
         }
     }
 }
diff --git a/src/bin/rsvg-convert/main.rs b/src/bin/rsvg-convert/main.rs
index 78fee0f2..91ad18c0 100644
--- a/src/bin/rsvg-convert/main.rs
+++ b/src/bin/rsvg-convert/main.rs
@@ -8,10 +8,13 @@ mod size;
 mod surface;
 
 use cssparser::Color;
+use gio::prelude::*;
+use gio::{Cancellable, FileExt, InputStream, UnixInputStream};
 use librsvg::rsvg_convert_only::LegacySize;
 use librsvg::{CairoRenderer, Loader, RenderingError};
 
 use crate::cli::Args;
+use crate::input::Input;
 use crate::output::Stream;
 use crate::size::{ResizeStrategy, Size};
 use crate::surface::Surface;
@@ -48,11 +51,25 @@ fn main() {
 
     let mut target = None;
 
-    for input in args.input() {
+    for input in &args.input {
+        let (stream, basefile) = match input {
+            Input::Stdin => {
+                let stream = unsafe { UnixInputStream::new(0) };
+                (stream.upcast::<InputStream>(), None)
+            }
+            Input::Path(p) => {
+                let file = gio::File::new_for_path(p);
+                let stream = file
+                    .read(None::<&Cancellable>)
+                    .unwrap_or_else(|e| exit!("Error reading file \"{}\": {}", input, e));
+                (stream.upcast::<InputStream>(), Some(file))
+            }
+        };
+
         let mut handle = Loader::new()
             .with_unlimited_size(args.unlimited)
             .keep_image_data(args.keep_image_data)
-            .read_stream(input.stream(), input.file(), None::<&gio::Cancellable>)
+            .read_stream(&stream, basefile.as_ref(), None::<&Cancellable>)
             .unwrap_or_else(|e| exit!("Error reading SVG {}: {}", input, e));
 
         if let Some(ref css) = stylesheet {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]