Skip to content

Commit

Permalink
serialize: Change some FnOnce bounds to FnMut
Browse files Browse the repository at this point in the history
Relax some of the bounds on the decoder methods back to FnMut to help accomodate
some more flavorful variants of decoders which may need to run the closure more
than once when it, for example, attempts to find the first successful enum to
decode.

This a breaking change due to the bounds for the trait switching, and clients
will need to update from `FnOnce` to `FnMut` as well as likely making the local
function binding mutable in order to call the function.

[breaking-change]
  • Loading branch information
alexcrichton committed Dec 15, 2014
1 parent ef0bc46 commit c9ea7c9
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 14 deletions.
14 changes: 8 additions & 6 deletions src/librbml/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,9 @@ pub mod reader {
Ok(result)
}

fn read_enum_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where
F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
fn read_enum_variant<T, F>(&mut self, _: &[&str],
mut f: F) -> DecodeResult<T>
where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
{
debug!("read_enum_variant()");
let idx = try!(self._next_uint(EsEnumVid));
Expand All @@ -526,8 +527,9 @@ pub mod reader {
f(self)
}

fn read_enum_struct_variant<T, F>(&mut self, _: &[&str], f: F) -> DecodeResult<T> where
F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
fn read_enum_struct_variant<T, F>(&mut self, _: &[&str],
mut f: F) -> DecodeResult<T>
where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
{
debug!("read_enum_struct_variant()");
let idx = try!(self._next_uint(EsEnumVid));
Expand Down Expand Up @@ -610,8 +612,8 @@ pub mod reader {
self.read_tuple_arg(idx, f)
}

fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where
F: FnOnce(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult<T>,
{
debug!("read_option()");
self.read_enum("Option", move |this| {
Expand Down
11 changes: 6 additions & 5 deletions src/libserialize/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2082,8 +2082,9 @@ impl ::Decoder<DecoderError> for Decoder {
f(self)
}

fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
fn read_enum_variant<T, F>(&mut self, names: &[&str],
mut f: F) -> DecodeResult<T>
where F: FnMut(&mut Decoder, uint) -> DecodeResult<T>,
{
debug!("read_enum_variant(names={})", names);
let name = match self.pop() {
Expand Down Expand Up @@ -2133,7 +2134,7 @@ impl ::Decoder<DecoderError> for Decoder {
}

fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> DecodeResult<T> where
F: FnOnce(&mut Decoder, uint) -> DecodeResult<T>,
F: FnMut(&mut Decoder, uint) -> DecodeResult<T>,
{
debug!("read_enum_struct_variant(names={})", names);
self.read_enum_variant(names, f)
Expand Down Expand Up @@ -2230,8 +2231,8 @@ impl ::Decoder<DecoderError> for Decoder {
self.read_tuple_arg(idx, f)
}

fn read_option<T, F>(&mut self, f: F) -> DecodeResult<T> where
F: FnOnce(&mut Decoder, bool) -> DecodeResult<T>,
fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T> where
F: FnMut(&mut Decoder, bool) -> DecodeResult<T>,
{
debug!("read_option()");
match self.pop() {
Expand Down
6 changes: 3 additions & 3 deletions src/libserialize/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ pub trait Decoder<E> {
F: FnOnce(&mut Self) -> Result<T, E>;

fn read_enum_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, E> where
F: FnOnce(&mut Self, uint) -> Result<T, E>;
F: FnMut(&mut Self, uint) -> Result<T, E>;
fn read_enum_variant_arg<T, F>(&mut self, a_idx: uint, f: F) -> Result<T, E> where
F: FnOnce(&mut Self) -> Result<T, E>;

fn read_enum_struct_variant<T, F>(&mut self, names: &[&str], f: F) -> Result<T, E> where
F: FnOnce(&mut Self, uint) -> Result<T, E>;
F: FnMut(&mut Self, uint) -> Result<T, E>;
fn read_enum_struct_variant_field<T, F>(&mut self,
&f_name: &str,
f_idx: uint,
Expand Down Expand Up @@ -154,7 +154,7 @@ pub trait Decoder<E> {

// Specialized types:
fn read_option<T, F>(&mut self, f: F) -> Result<T, E> where
F: FnOnce(&mut Self, bool) -> Result<T, E>;
F: FnMut(&mut Self, bool) -> Result<T, E>;

fn read_seq<T, F>(&mut self, f: F) -> Result<T, E> where
F: FnOnce(&mut Self, uint) -> Result<T, E>;
Expand Down

1 comment on commit c9ea7c9

@BurntSushi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexcrichton This is awesome. Thank you. :-)

(I was using this functionality in rust-csv and had to disable it.)

Please sign in to comment.