Skip to content

Commit 295208a

Browse files
authored
Merge pull request #213 from bluss/default
Implement Default for owned arrays
2 parents 6169ea2 + a936621 commit 295208a

File tree

7 files changed

+155
-122
lines changed

7 files changed

+155
-122
lines changed

src/arraydeserialize.rs renamed to src/array_serde.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,51 @@
55
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
8-
use serde::{self, Deserialize};
9-
10-
use std::marker::PhantomData;
8+
use serde::{self, Serialize, Deserialize};
119

1210
use imp_prelude::*;
1311

1412
use super::arraytraits::ARRAY_FORMAT_VERSION;
13+
use super::Elements;
14+
15+
use std::marker::PhantomData;
16+
17+
/// **Requires crate feature `"serde"`**
18+
impl<A, D, S> Serialize for ArrayBase<S, D>
19+
where A: Serialize,
20+
D: Dimension + Serialize,
21+
S: Data<Elem = A>
22+
23+
{
24+
fn serialize<Se>(&self, serializer: &mut Se) -> Result<(), Se::Error>
25+
where Se: serde::Serializer
26+
{
27+
let mut struct_state = try!(serializer.serialize_struct("Array", 3));
28+
try!(serializer.serialize_struct_elt(&mut struct_state, "v", ARRAY_FORMAT_VERSION));
29+
try!(serializer.serialize_struct_elt(&mut struct_state, "dim", self.dim()));
30+
try!(serializer.serialize_struct_elt(&mut struct_state, "data", Sequence(self.iter())));
31+
serializer.serialize_struct_end(struct_state)
32+
}
33+
}
34+
35+
// private iterator wrapper
36+
struct Sequence<'a, A: 'a, D>(Elements<'a, A, D>);
37+
38+
impl<'a, A, D> Serialize for Sequence<'a, A, D>
39+
where A: Serialize,
40+
D: Dimension + Serialize
41+
{
42+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
43+
where S: serde::Serializer
44+
{
45+
let iter = &self.0;
46+
let mut seq_state = try!(serializer.serialize_seq(Some(iter.len())));
47+
for elt in iter.clone() {
48+
try!(serializer.serialize_seq_elt(&mut seq_state, elt));
49+
}
50+
serializer.serialize_seq_end(seq_state)
51+
}
52+
}
1553

1654
struct ArrayVisitor<S, Di> {
1755
_marker_a: PhantomData<S>,

src/array_serialize.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2014-2016 bluss and ndarray developers.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
use serialize::{Encodable, Encoder, Decodable, Decoder};
10+
use super::arraytraits::ARRAY_FORMAT_VERSION;
11+
12+
use imp_prelude::*;
13+
14+
/// **Requires crate feature `"rustc-serialize"`**
15+
impl<A, S, D> Encodable for ArrayBase<S, D>
16+
where A: Encodable,
17+
D: Dimension + Encodable,
18+
S: Data<Elem = A>
19+
{
20+
fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
21+
s.emit_struct("Array", 3, |e| {
22+
try!(e.emit_struct_field("v", 0, |e| ARRAY_FORMAT_VERSION.encode(e)));
23+
// FIXME: Write self.dim as a slice (self.shape)
24+
// The problem is decoding it.
25+
try!(e.emit_struct_field("dim", 1, |e| self.dim.encode(e)));
26+
try!(e.emit_struct_field("data", 2, |e| {
27+
let sz = self.dim.size();
28+
e.emit_seq(sz, |e| {
29+
for (i, elt) in self.iter().enumerate() {
30+
try!(e.emit_seq_elt(i, |e| elt.encode(e)))
31+
}
32+
Ok(())
33+
})
34+
}));
35+
Ok(())
36+
})
37+
}
38+
}
39+
40+
/// **Requires crate feature `"rustc-serialize"`**
41+
impl<A, S, D> Decodable for ArrayBase<S, D>
42+
where A: Decodable,
43+
D: Dimension + Decodable,
44+
S: DataOwned<Elem = A>
45+
{
46+
fn decode<E: Decoder>(d: &mut E) -> Result<ArrayBase<S, D>, E::Error> {
47+
d.read_struct("Array", 3, |d| {
48+
let version: u8 = try!(d.read_struct_field("v", 0, Decodable::decode));
49+
if version > ARRAY_FORMAT_VERSION {
50+
return Err(d.error("unknown array version"))
51+
}
52+
let dim: D = try!(d.read_struct_field("dim", 1, |d| {
53+
Decodable::decode(d)
54+
}));
55+
56+
let elements = try!(
57+
d.read_struct_field("data", 2, |d| {
58+
d.read_seq(|d, len| {
59+
if len != dim.size() {
60+
Err(d.error("data and dimension must match in size"))
61+
} else {
62+
let mut elements = Vec::with_capacity(len);
63+
for i in 0..len {
64+
elements.push(try!(d.read_seq_elt::<A, _>(i, Decodable::decode)))
65+
}
66+
Ok(elements)
67+
}
68+
})
69+
}));
70+
unsafe {
71+
Ok(ArrayBase::from_shape_vec_unchecked(dim, elements))
72+
}
73+
})
74+
}
75+
}
76+

src/arrayserialize.rs

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/arraytraits.rs

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -212,71 +212,6 @@ unsafe impl<S, D> Send for ArrayBase<S, D>
212212
// Use version number so we can add a packed format later.
213213
pub const ARRAY_FORMAT_VERSION: u8 = 1u8;
214214

215-
/// **Requires crate feature `"rustc-serialize"`**
216-
#[cfg(feature = "rustc-serialize")]
217-
impl<A, S, D> Encodable for ArrayBase<S, D>
218-
where A: Encodable,
219-
D: Dimension + Encodable,
220-
S: Data<Elem = A>
221-
{
222-
fn encode<E: Encoder>(&self, s: &mut E) -> Result<(), E::Error> {
223-
s.emit_struct("Array", 3, |e| {
224-
try!(e.emit_struct_field("v", 0, |e| ARRAY_FORMAT_VERSION.encode(e)));
225-
// FIXME: Write self.dim as a slice (self.shape)
226-
// The problem is decoding it.
227-
try!(e.emit_struct_field("dim", 1, |e| self.dim.encode(e)));
228-
try!(e.emit_struct_field("data", 2, |e| {
229-
let sz = self.dim.size();
230-
e.emit_seq(sz, |e| {
231-
for (i, elt) in self.iter().enumerate() {
232-
try!(e.emit_seq_elt(i, |e| elt.encode(e)))
233-
}
234-
Ok(())
235-
})
236-
}));
237-
Ok(())
238-
})
239-
}
240-
}
241-
242-
/// **Requires crate feature `"rustc-serialize"`**
243-
#[cfg(feature = "rustc-serialize")]
244-
impl<A, S, D> Decodable for ArrayBase<S, D>
245-
where A: Decodable,
246-
D: Dimension + Decodable,
247-
S: DataOwned<Elem = A>
248-
{
249-
fn decode<E: Decoder>(d: &mut E) -> Result<ArrayBase<S, D>, E::Error> {
250-
d.read_struct("Array", 3, |d| {
251-
let version: u8 = try!(d.read_struct_field("v", 0, Decodable::decode));
252-
if version > ARRAY_FORMAT_VERSION {
253-
return Err(d.error("unknown array version"))
254-
}
255-
let dim: D = try!(d.read_struct_field("dim", 1, |d| {
256-
Decodable::decode(d)
257-
}));
258-
259-
let elements = try!(
260-
d.read_struct_field("data", 2, |d| {
261-
d.read_seq(|d, len| {
262-
if len != dim.size() {
263-
Err(d.error("data and dimension must match in size"))
264-
} else {
265-
let mut elements = Vec::with_capacity(len);
266-
for i in 0..len {
267-
elements.push(try!(d.read_seq_elt::<A, _>(i, Decodable::decode)))
268-
}
269-
Ok(elements)
270-
}
271-
})
272-
}));
273-
unsafe {
274-
Ok(ArrayBase::from_shape_vec_unchecked(dim, elements))
275-
}
276-
})
277-
}
278-
}
279-
280215

281216
// use "raw" form instead of type aliases here so that they show up in docs
282217
/// Implementation of `ArrayView::from(&S)` where `S` is a slice or slicable.
@@ -357,3 +292,25 @@ impl<'a, A: 'a, D, T> AsArray<'a, A, D> for T
357292
where T: Into<ArrayView<'a, A, D>>,
358293
D: Dimension,
359294
{ }
295+
296+
/// Create an owned array with a default state.
297+
///
298+
/// The array is created with dimension `D::default()`, which results
299+
/// in for example dimensions `0` and `(0, 0)` with zero elements for the
300+
/// one-dimensional and two-dimensional cases respectively, while for example
301+
/// the zero dimensional case uses `()` (or `Vec::new()`) which
302+
/// results in an array with one element.
303+
///
304+
/// Since arrays cannot grow, the intention is to use the default value as
305+
/// placeholder.
306+
impl<A, S, D> Default for ArrayBase<S, D>
307+
where S: DataOwned<Elem=A>,
308+
D: Dimension,
309+
A: Default,
310+
{
311+
// NOTE: We can implement Default for non-zero dimensional array views by
312+
// using an empty slice, however we need a trait for nonzero Dimension.
313+
fn default() -> Self {
314+
ArrayBase::default(D::default())
315+
}
316+
}

src/dimension.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn stride_offset_checked_arithmetic<D>(dim: &D, strides: &D, index: &D)
124124
///
125125
/// ***Don't implement or call methods in this trait, its interface is internal
126126
/// to the crate and will evolve at will.***
127-
pub unsafe trait Dimension : Clone + Eq + Debug + Send + Sync {
127+
pub unsafe trait Dimension : Clone + Eq + Debug + Send + Sync + Default {
128128
/// `SliceArg` is the type which is used to specify slicing for this
129129
/// dimension.
130130
///

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ pub use shape_builder::{ ShapeBuilder };
116116

117117
mod arraytraits;
118118
#[cfg(feature = "serde")]
119-
mod arrayserialize;
120-
#[cfg(feature = "serde")]
121-
mod arraydeserialize;
119+
mod array_serde;
120+
#[cfg(feature = "rustc-serialize")]
121+
mod array_serialize;
122122
mod arrayformat;
123123
mod data_traits;
124124

tests/array.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,3 +1050,15 @@ fn test_view_from_shape_ptr() {
10501050
view[[0, 1]] = 0;
10511051
assert_eq!(view, aview2(&[[0, 0, 2], [3, 4, 6]]));
10521052
}
1053+
1054+
#[test]
1055+
fn test_default() {
1056+
let a = <Array<f32, (Ix, Ix)> as Default>::default();
1057+
assert_eq!(a, aview2(&[[0.0; 0]; 0]));
1058+
1059+
1060+
#[derive(Default, Debug, PartialEq)]
1061+
struct Foo(i32);
1062+
let b = <Array<Foo, ()> as Default>::default();
1063+
assert_eq!(b, arr0(Foo::default()));
1064+
}

0 commit comments

Comments
 (0)