Skip to content

Commit

Permalink
std io error (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
avl authored Oct 11, 2024
1 parent f1cdbd9 commit 968cabc
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 14 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ fn main() {
See the docs for more information, including schema-versioning: https://docs.rs/savefile/latest/savefile/ .

# Changelog

## 0.17.10

Support for serializing the std::io::Error type.
Note, non-stabilized Error-kinds are not supported.

## 0.17.9

Replace the un-maintained proc-macro-error with proc-macro-error2.
Expand Down
6 changes: 3 additions & 3 deletions savefile-abi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "savefile-abi"
version = "0.17.9"
version = "0.17.10"
edition = "2021"
authors = ["Anders Musikka <[email protected]>"]
documentation = "https://docs.rs/savefile-abi/"
Expand All @@ -17,8 +17,8 @@ keywords = ["dylib", "dlopen", "ffi"]
license = "MIT/Apache-2.0"

[dependencies]
savefile = { path="../savefile", version = "=0.17.9" }
savefile-derive = { path="../savefile-derive", version = "=0.17.9" }
savefile = { path="../savefile", version = "=0.17.10" }
savefile-derive = { path="../savefile-derive", version = "=0.17.10" }
byteorder = "1.4"
libloading = "0.8"

Expand Down
2 changes: 1 addition & 1 deletion savefile-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "savefile-derive"
version = "0.17.9"
version = "0.17.10"
authors = ["Anders Musikka <[email protected]>"]
repository = "https://github.com/avl/savefile"
rust-version = "1.74"
Expand Down
2 changes: 1 addition & 1 deletion savefile-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ nightly=["savefile/nightly"]

[dependencies]
savefile = { path = "../savefile", features = ["size_sanity_checks", "encryption", "compression","bit-set","bit-vec","rustc-hash","serde_derive", "quickcheck", "nalgebra"]}
savefile-derive = { path = "../savefile-derive", version = "=0.17.9" }
savefile-derive = { path = "../savefile-derive", version = "=0.17.10" }
savefile-abi = { path = "../savefile-abi" }
bit-vec = "0.8"
arrayvec="0.7"
Expand Down
38 changes: 37 additions & 1 deletion savefile-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use indexmap::IndexMap;
use indexmap::IndexSet;
use savefile::prelude::*;
use std::fmt::Debug;
use std::io::Write;
use std::io::{ErrorKind, Write};
extern crate arrayvec;
extern crate bincode;
extern crate parking_lot;
Expand Down Expand Up @@ -84,6 +84,26 @@ pub fn assert_roundtrip_version<E: Serialize + Deserialize + Debug + PartialEq>(
assert_eq!(f.position() as usize, f_internal_size);
}

pub fn assert_roundtrip_by<E: Serialize + Deserialize + Debug>(sample: E, comp: impl Fn(E, E) -> bool) {
let mut f = Cursor::new(Vec::new());
{
let mut bufw = BufWriter::new(&mut f);
{
Serializer::save(&mut bufw, 1, &sample, false).unwrap();
}
bufw.flush().unwrap();
}
f.set_position(0);
{
let roundtrip_result = Deserializer::load::<E>(&mut f, 1).unwrap();
assert!(comp(sample, roundtrip_result));
}

let f_internal_size = f.get_ref().len();
assert_eq!(f.position() as usize, f_internal_size);
}


pub fn assert_roundtrip_debug<E: Serialize + Deserialize + Debug>(sample: E) {
let sample_debug_string = format!("{:?}", sample);
let round_tripped = roundtrip(sample);
Expand Down Expand Up @@ -1502,6 +1522,22 @@ pub fn test_unit_struct() {
let h = MyUnitStruct;
assert_roundtrip(h);
}
#[test]
fn roundtrip_io_error() {
fn assert_error_roundtrip(err: std::io::Error) {
assert_roundtrip_by(
err,
|a,b|{
a.kind() == b.kind() &&
a.to_string() == b.to_string()
}
);
}
assert_error_roundtrip(std::io::Error::new(ErrorKind::AddrNotAvailable,"Hello"));
assert_error_roundtrip(std::io::Error::new(ErrorKind::AddrInUse,"Hello2"));
assert_error_roundtrip(std::io::Error::new(ErrorKind::Other,"Hello3"));
assert_error_roundtrip(std::io::Error::new(ErrorKind::TimedOut,"Hello4"));
}

#[test]
pub fn test_zero_size_vec_items() {
Expand Down
6 changes: 3 additions & 3 deletions savefile/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "savefile"
version = "0.17.9"
version = "0.17.10"
authors = ["Anders Musikka <[email protected]>"]
documentation = "https://docs.rs/savefile/"
homepage = "https://github.com/avl/savefile/"
Expand Down Expand Up @@ -63,13 +63,13 @@ bit-set08 = {package="bit-set", version = "0.8", optional = true}
rustc-hash = {version = "1.1", optional = true}
memoffset = "0.9"
byteorder = "1.4"
savefile-derive = {path="../savefile-derive", version = "=0.17.9", optional = true }
savefile-derive = {path="../savefile-derive", version = "=0.17.10", optional = true }
serde_derive = {version= "1.0", optional = true}
serde = {version= "1.0", optional = true}
quickcheck = {version= "1.0", optional = true}

[dev-dependencies]
savefile-derive = { path="../savefile-derive", version = "=0.17.9" }
savefile-derive = { path="../savefile-derive", version = "=0.17.10" }

[build-dependencies]
rustc_version="0.2"
Expand Down
89 changes: 87 additions & 2 deletions savefile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ use parking_lot::{Mutex, MutexGuard, RwLock, RwLockReadGuard};

use std::borrow::Cow;
use std::fs::File;
use std::io::Write;
use std::io::{ErrorKind, Write};
use std::io::{BufReader, BufWriter, Read};
use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU64, AtomicU8,
Expand Down Expand Up @@ -1360,6 +1360,79 @@ impl<'a, T: 'a + Introspect + ToOwned + ?Sized> Introspect for Cow<'a, T> {
}
}

impl WithSchema for std::io::Error {
fn schema(_version: u32, _context: &mut WithSchemaContext) -> Schema {
Schema::StdIoError
}
}
impl Packed for std::io::Error {}

impl Serialize for std::io::Error {
fn serialize(&self, serializer: &mut Serializer<impl Write>) -> Result<(), SavefileError> {
let kind = match self.kind() {
ErrorKind::NotFound => {1}
ErrorKind::PermissionDenied => {2}
ErrorKind::ConnectionRefused => {3}
ErrorKind::ConnectionReset => {4}
ErrorKind::ConnectionAborted => {7}
ErrorKind::NotConnected => {8}
ErrorKind::AddrInUse => {9}
ErrorKind::AddrNotAvailable => {10}
ErrorKind::BrokenPipe => {12}
ErrorKind::AlreadyExists => {13}
ErrorKind::WouldBlock => {14}
ErrorKind::InvalidInput => {21}
ErrorKind::InvalidData => {22}
ErrorKind::TimedOut => {23}
ErrorKind::WriteZero => {24}
ErrorKind::Interrupted => {36}
ErrorKind::Unsupported => {37}
ErrorKind::UnexpectedEof => {38}
ErrorKind::OutOfMemory => {39}
ErrorKind::Other => {40}
_ => {
42
}
};
serializer.write_u16(kind as u16)?;
serializer.write_string(&self.to_string())?;
Ok(())
}
}
impl Deserialize for std::io::Error {
fn deserialize(deserializer: &mut Deserializer<impl Read>) -> Result<Self, SavefileError> {
let kind = deserializer.read_u16()?;
let kind = match kind {
1 => ErrorKind::NotFound,
2 => ErrorKind::PermissionDenied,
3 => ErrorKind::ConnectionRefused,
4 => ErrorKind::ConnectionReset,
7 => ErrorKind::ConnectionAborted,
8 => ErrorKind::NotConnected,
9 => ErrorKind::AddrInUse,
10 => ErrorKind::AddrNotAvailable,
12 => ErrorKind::BrokenPipe,
13 => ErrorKind::AlreadyExists,
14 => ErrorKind::WouldBlock,
21 => ErrorKind::InvalidInput,
22 => ErrorKind::InvalidData,
23 => ErrorKind::TimedOut,
24 => ErrorKind::WriteZero,
36 => ErrorKind::Interrupted,
37 => ErrorKind::Unsupported,
38 => ErrorKind::UnexpectedEof,
39 => ErrorKind::OutOfMemory,
40 => ErrorKind::Other,
_ => {
ErrorKind::Other
}
};

let string = String::deserialize(deserializer)?;
Ok(std::io::Error::new(kind, string))
}
}

#[cfg(feature = "ring")]
mod crypto {
use ring::aead;
Expand Down Expand Up @@ -3243,6 +3316,8 @@ pub enum Schema {
/// if it is identical in memory and file, and because of this, counting
/// only the recursion points is non-ambiguous.
Recursion(usize /*depth*/),
/// std::io::Error
StdIoError,
}
/// Introspect is not implemented for Schema, though it could be
impl Introspect for Schema {
Expand Down Expand Up @@ -3278,6 +3353,7 @@ impl Schema {
Schema::Recursion(depth) => {
format!("<recursion {}>", depth)
}
Schema::StdIoError => "stdioerror".into(),
}
}
/// Determine if the two fields are laid out identically in memory, in their parent objects.
Expand Down Expand Up @@ -3432,6 +3508,7 @@ impl Schema {
Schema::Reference(_) => None,
Schema::Trait(_, _) => None,
Schema::Recursion(_) => None,
Schema::StdIoError => None,
}
}
}
Expand Down Expand Up @@ -3574,6 +3651,9 @@ pub fn diff_schema(a: &Schema, b: &Schema, path: String) -> Option<String> {
(Schema::Str, Schema::Str) => {
return None;
}
(Schema::StdIoError, Schema::StdIoError) => {
return None;
}
(Schema::Boxed(a), Schema::Boxed(b)) => {
return diff_schema(&**a, &**b, path);
}
Expand Down Expand Up @@ -4135,6 +4215,10 @@ impl Serialize for Schema {
serializer.write_usize(*depth)?;
Ok(())
}
Schema::StdIoError => {
serializer.write_u8(17)?;
Ok(())
}
}
}
}
Expand Down Expand Up @@ -4173,9 +4257,10 @@ impl Deserialize for Schema {
<_ as Deserialize>::deserialize(deserializer)?,
),
16 => Schema::Recursion(<_ as Deserialize>::deserialize(deserializer)?),
17 => Schema::StdIoError,
c => {
return Err(SavefileError::GeneralError {
msg: format!("Corrupt schema, schema variant {} encountered", c),
msg: format!("Corrupt, or future schema, schema variant {} encountered", c),
})
}
};
Expand Down

0 comments on commit 968cabc

Please sign in to comment.