From 5d3116edc2500be95cfc19f1b10a32e89005960e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 15 Jun 2023 21:11:32 -0700 Subject: [PATCH] Add Error::io_error_kind --- src/error.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- src/io/core.rs | 4 ++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 52169a058..4f8779694 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,6 +1,6 @@ //! When serializing or deserializing JSON goes wrong. -use crate::io; +use crate::io::{self, ErrorKind}; use alloc::boxed::Box; use alloc::string::{String, ToString}; use core::fmt::{self, Debug, Display}; @@ -105,6 +105,54 @@ impl Error { pub fn is_eof(&self) -> bool { self.classify() == Category::Eof } + + /// The kind reported by the underlying standard library I/O error, if this + /// error was caused by a failure to read or write bytes on an I/O stream. + /// + /// # Example + /// + /// ``` + /// use serde_json::Value; + /// use std::io::{self, ErrorKind, Read}; + /// use std::process; + /// + /// struct ReaderThatWillTimeOut<'a>(&'a [u8]); + /// + /// impl<'a> Read for ReaderThatWillTimeOut<'a> { + /// fn read(&mut self, buf: &mut [u8]) -> io::Result { + /// if self.0.is_empty() { + /// Err(io::Error::new(ErrorKind::TimedOut, "timed out")) + /// } else { + /// self.0.read(buf) + /// } + /// } + /// } + /// + /// fn main() { + /// let reader = ReaderThatWillTimeOut(br#" {"k": "#); + /// + /// let _: Value = match serde_json::from_reader(reader) { + /// Ok(value) => value, + /// Err(error) => { + /// if error.io_error_kind() == Some(ErrorKind::TimedOut) { + /// // Maybe this application needs to retry certain kinds of errors. + /// + /// # return; + /// } else { + /// eprintln!("error: {}", error); + /// process::exit(1); + /// } + /// } + /// }; + /// } + /// ``` + pub fn io_error_kind(&self) -> Option { + if let ErrorCode::Io(io_error) = &self.err.code { + Some(io_error.kind()) + } else { + None + } + } } /// Categorizes the cause of a `serde_json::Error`. diff --git a/src/io/core.rs b/src/io/core.rs index 54c8ddfda..32039852d 100644 --- a/src/io/core.rs +++ b/src/io/core.rs @@ -23,6 +23,10 @@ impl Error { pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error { Error } + + pub(crate) fn kind(&self) -> ErrorKind { + ErrorKind::Other + } } pub type Result = result::Result;