Skip to content

Commit

Permalink
Remove quick_xml::Result from public api
Browse files Browse the repository at this point in the history
The quick_xml::Writer will never return anything but io errors, so the
returned error is "unwrapped" to the underlying `std::io::Result` and
returned directly
  • Loading branch information
RedPhoenixQ committed Sep 28, 2024
1 parent e16fe77 commit d4215a4
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 76 deletions.
4 changes: 1 addition & 3 deletions src/bin/flamegraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ impl<'a> Opt {

const PALETTE_MAP_FILE: &str = "palette.map"; // default name for the palette map file

fn main() -> quick_xml::Result<()> {
fn main() -> io::Result<()> {
let opt = Opt::parse();

// Initialize logger
Expand Down Expand Up @@ -344,8 +344,6 @@ fn main() -> quick_xml::Result<()> {
}

save_consistent_palette_if_needed(&palette_map, PALETTE_MAP_FILE)
.map_err(std::sync::Arc::new)
.map_err(quick_xml::Error::Io)
}

fn fetch_consistent_palette_if_needed(
Expand Down
8 changes: 4 additions & 4 deletions src/flamegraph/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn flow<'a, LI, TI>(
pub(super) fn frames<'a, I>(
lines: I,
suppress_sort_check: bool,
) -> quick_xml::Result<(Vec<TimedFrame<'a>>, usize, usize, usize)>
) -> io::Result<(Vec<TimedFrame<'a>>, usize, usize, usize)>
where
I: IntoIterator<Item = &'a str>,
{
Expand All @@ -128,9 +128,9 @@ where
if !suppress_sort_check {
if let Some(prev_line) = prev_line {
if prev_line > line {
return Err(quick_xml::Error::Io(
io::Error::new(io::ErrorKind::InvalidData, "unsorted input lines detected")
.into(),
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"unsorted input lines detected",
));
}
}
Expand Down
80 changes: 42 additions & 38 deletions src/flamegraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl Rectangle {
///
/// [differential flame graph]: http://www.brendangregg.com/blog/2014-11-09/differential-flame-graphs.html
#[allow(clippy::cognitive_complexity)]
pub fn from_lines<'a, I, W>(opt: &mut Options<'_>, lines: I, writer: W) -> quick_xml::Result<()>
pub fn from_lines<'a, I, W>(opt: &mut Options<'_>, lines: I, writer: W) -> io::Result<()>
where
I: IntoIterator<Item = &'a str>,
W: Write,
Expand Down Expand Up @@ -498,10 +498,12 @@ where
extra: None,
},
)?;
svg.write_event(Event::End(BytesEnd::new("svg")))?;
svg.write_event(Event::Eof)?;
return Err(quick_xml::Error::Io(
io::Error::new(io::ErrorKind::InvalidData, "No stack counts found").into(),
svg.write_event(Event::End(BytesEnd::new("svg")))
.map_err(to_io_err)?;
svg.write_event(Event::Eof).map_err(to_io_err)?;
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"No stack counts found",
));
}

Expand Down Expand Up @@ -561,7 +563,8 @@ where
("x", &container_x),
("width", &container_width),
("total_samples", &format!("{}", timemax)),
])))?;
])))
.map_err(to_io_err)?;

// draw frames
let mut samples_txt_buffer = num_format::Buffer::default();
Expand Down Expand Up @@ -644,9 +647,12 @@ where
&buffer[info],
)?;

svg.write_event(Event::Start(BytesStart::new("title")))?;
svg.write_event(Event::Text(BytesText::new(title)))?;
svg.write_event(Event::End(BytesEnd::new("title")))?;
svg.write_event(Event::Start(BytesStart::new("title")))
.map_err(to_io_err)?;
svg.write_event(Event::Text(BytesText::new(title)))
.map_err(to_io_err)?;
svg.write_event(Event::End(BytesEnd::new("title")))
.map_err(to_io_err)?;

// select the color of the rectangle
let color = if frame.location.function == "--" {
Expand Down Expand Up @@ -723,15 +729,17 @@ where

buffer.clear();
if has_href {
svg.write_event(cache_a_end.borrow())?;
svg.write_event(cache_a_end.borrow()).map_err(to_io_err)?;
} else {
svg.write_event(cache_g_end.borrow())?;
svg.write_event(cache_g_end.borrow()).map_err(to_io_err)?;
}
}

svg.write_event(Event::End(BytesEnd::new("svg")))?;
svg.write_event(Event::End(BytesEnd::new("svg")))?;
svg.write_event(Event::Eof)?;
svg.write_event(Event::End(BytesEnd::new("svg")))
.map_err(to_io_err)?;
svg.write_event(Event::End(BytesEnd::new("svg")))
.map_err(to_io_err)?;
svg.write_event(Event::Eof).map_err(to_io_err)?;

svg.into_inner().flush()?;
Ok(())
Expand All @@ -745,7 +753,7 @@ fn write_container_start<'a, W: Write>(
cache_g: &mut Event<'_>,
frame: &merge::TimedFrame<'_>,
mut title: &'a str,
) -> quick_xml::Result<(bool, &'a str)> {
) -> io::Result<(bool, &'a str)> {
let frame_attributes = opt
.func_frameattrs
.frameattrs_for_func(frame.location.function);
Expand All @@ -754,18 +762,18 @@ fn write_container_start<'a, W: Write>(
if let Some(frame_attributes) = frame_attributes {
if frame_attributes.attrs.contains_key("xlink:href") {
write_container_attributes(cache_a, frame_attributes);
svg.write_event(cache_a.borrow())?;
svg.write_event(cache_a.borrow()).map_err(to_io_err)?;
has_href = true;
} else {
write_container_attributes(cache_g, frame_attributes);
svg.write_event(cache_g.borrow())?;
svg.write_event(cache_g.borrow()).map_err(to_io_err)?;
}
if let Some(ref t) = frame_attributes.title {
title = t.as_str();
}
} else if let Event::Start(ref mut c) = cache_g {
c.clear_attributes();
svg.write_event(cache_g.borrow())?;
svg.write_event(cache_g.borrow()).map_err(to_io_err)?;
}

Ok((has_href, title))
Expand All @@ -779,7 +787,7 @@ fn write_container_start<'a, W: Write>(
cache_g: &mut Event<'_>,
_frame: &merge::TimedFrame<'_>,
title: &'a str,
) -> quick_xml::Result<(bool, &'a str)> {
) -> io::Result<(bool, &'a str)> {
if let Event::Start(ref mut c) = cache_g {
c.clear_attributes();
svg.write_event(cache_g.borrow())?;
Expand Down Expand Up @@ -809,7 +817,7 @@ fn write_container_attributes(event: &mut Event<'_>, frame_attributes: &FrameAtt
/// See [`from_lines`] for the expected format of each line.
///
/// The resulting flame graph will be written out to `writer` in SVG format.
pub fn from_reader<R, W>(opt: &mut Options<'_>, reader: R, writer: W) -> quick_xml::Result<()>
pub fn from_reader<R, W>(opt: &mut Options<'_>, reader: R, writer: W) -> io::Result<()>
where
R: Read,
W: Write,
Expand All @@ -822,18 +830,15 @@ where
/// See [`from_lines`] for the expected format of each line.
///
/// The resulting flame graph will be written out to `writer` in SVG format.
pub fn from_readers<R, W>(opt: &mut Options<'_>, readers: R, writer: W) -> quick_xml::Result<()>
pub fn from_readers<R, W>(opt: &mut Options<'_>, readers: R, writer: W) -> io::Result<()>
where
R: IntoIterator,
R::Item: Read,
W: Write,
{
let mut input = String::new();
for mut reader in readers {
reader
.read_to_string(&mut input)
.map_err(std::sync::Arc::new)
.map_err(quick_xml::Error::Io)?;
reader.read_to_string(&mut input)?;
}
from_lines(opt, input.lines(), writer)
}
Expand All @@ -842,19 +847,13 @@ where
/// and write the result to provided `writer`.
///
/// If files is empty, STDIN will be used as input.
pub fn from_files<W: Write>(
opt: &mut Options<'_>,
files: &[PathBuf],
writer: W,
) -> quick_xml::Result<()> {
pub fn from_files<W: Write>(opt: &mut Options<'_>, files: &[PathBuf], writer: W) -> io::Result<()> {
if files.is_empty() || files.len() == 1 && files[0].to_str() == Some("-") {
let stdin = io::stdin();
let r = BufReader::with_capacity(128 * 1024, stdin.lock());
from_reader(opt, r, writer)
} else if files.len() == 1 {
let r = File::open(&files[0])
.map_err(std::sync::Arc::new)
.map_err(quick_xml::Error::Io)?;
let r = File::open(&files[0])?;
from_reader(opt, r, writer)
} else {
let stdin = io::stdin();
Expand All @@ -868,9 +867,7 @@ pub fn from_files<W: Write>(
stdin_added = true;
}
} else {
let r = File::open(infile)
.map_err(std::sync::Arc::new)
.map_err(quick_xml::Error::Io)?;
let r = File::open(infile)?;
readers.push(Box::new(r));
}
}
Expand All @@ -896,7 +893,7 @@ fn filled_rectangle<W: Write>(
rect: &Rectangle,
color: Color,
cache_rect: &mut Event<'_>,
) -> quick_xml::Result<()> {
) -> io::Result<()> {
let x = write!(buffer, "{:.4}%", rect.x1_pct);
let y = write_usize(buffer, rect.y1);
let width = write!(buffer, "{:.4}%", rect.width_pct());
Expand All @@ -920,13 +917,20 @@ fn filled_rectangle<W: Write>(
} else {
unreachable!("cache wrapper was of wrong type: {:?}", cache_rect);
}
svg.write_event(cache_rect.borrow())
svg.write_event(cache_rect.borrow()).map_err(to_io_err)
}

fn write_usize(buffer: &mut StrStack, value: usize) -> usize {
buffer.push(itoa::Buffer::new().format(value))
}

fn to_io_err(err: quick_xml::Error) -> io::Error {
let quick_xml::Error::Io(err) = err else {
unreachable!("quick_xml write operations can only ever return std::io errors")
};
std::sync::Arc::into_inner(err).expect("Error value to be present when given by quick_xml")
}

#[cfg(test)]
mod tests {
use super::{Direction, Options};
Expand Down
Loading

0 comments on commit d4215a4

Please sign in to comment.