From: Ian Jackson Date: Sun, 16 May 2021 12:18:20 +0000 (+0100) Subject: packetframe: Fuse: retain the inner RW when broken X-Git-Tag: otter-0.6.0~233 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=d91417ebb487d3c235411a680795d8da370980bb;p=otter.git packetframe: Fuse: retain the inner RW when broken We are going to want this for AsRawFd, which needs to work even when broken since it is supposed to be infallible. Signed-off-by: Ian Jackson --- diff --git a/src/packetframe.rs b/src/packetframe.rs index 58e30379..349d7ea1 100644 --- a/src/packetframe.rs +++ b/src/packetframe.rs @@ -32,7 +32,7 @@ type BO = BigEndian; pub struct SenderError; #[derive(Debug)] -pub struct Fuse{ inner: Result } +pub struct Fuse{ inner: Result> } /// An error saved by `Fuse` so it can be repeatedly returned. #[derive(Clone,Error,Debug)] @@ -41,6 +41,12 @@ pub struct Broken { kind: io::ErrorKind, } +#[derive(Debug)] +pub struct BrokenFuse { + inner: Option, // always Some unless we panic crazily + error: Broken, +} + // ---------- read ---------- #[derive(Debug)] @@ -114,7 +120,7 @@ impl Fuse { #[throws(io::Error)] pub fn get(&mut self) -> &mut RW { - self.inner.as_mut().map_err(|broken| broken.clone())? + self.inner.as_mut().map_err(|broken| broken.error.clone())? } #[throws(io::Error)] @@ -124,10 +130,17 @@ impl Fuse { let inner = self.get()?; let r = f(inner); if let Err(e) = &r { - self.inner = Err(Broken { + let error = Broken { msg: e.to_string(), kind: e.kind(), - }); + }; + let inner = mem::replace(&mut self.inner, Err(BrokenFuse { + inner: None, + error, + })); + self.inner.as_mut().map(|_|()).unwrap_err().inner = Some( + inner.map_err(|e| e.error).unwrap() + ); } r? }