Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 72 additions & 75 deletions src/bson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,71 +87,71 @@ impl Default for Bson {

impl Debug for Bson {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Bson::FloatingPoint(p) => write!(f, "FloatingPoint({:?})", p),
&Bson::String(ref s) => write!(f, "String({:?})", s),
&Bson::Array(ref vec) => write!(f, "Array({:?})", vec),
&Bson::Document(ref doc) => write!(f, "Document({:?})", doc),
&Bson::Boolean(b) => write!(f, "Boolean({:?})", b),
&Bson::Null => write!(f, "Null"),
&Bson::RegExp(ref pat, ref opt) => write!(f, "RegExp(/{:?}/{:?})", pat, opt),
&Bson::JavaScriptCode(ref s) => write!(f, "JavaScriptCode({:?})", s),
&Bson::JavaScriptCodeWithScope(ref s, ref scope) => {
match *self {
Bson::FloatingPoint(p) => write!(f, "FloatingPoint({:?})", p),
Bson::String(ref s) => write!(f, "String({:?})", s),
Bson::Array(ref vec) => write!(f, "Array({:?})", vec),
Bson::Document(ref doc) => write!(f, "Document({:?})", doc),
Bson::Boolean(b) => write!(f, "Boolean({:?})", b),
Bson::Null => write!(f, "Null"),
Bson::RegExp(ref pat, ref opt) => write!(f, "RegExp(/{:?}/{:?})", pat, opt),
Bson::JavaScriptCode(ref s) => write!(f, "JavaScriptCode({:?})", s),
Bson::JavaScriptCodeWithScope(ref s, ref scope) => {
write!(f, "JavaScriptCodeWithScope({:?}, {:?})", s, scope)
}
&Bson::I32(v) => write!(f, "I32({:?})", v),
&Bson::I64(v) => write!(f, "I64({:?})", v),
&Bson::TimeStamp(i) => {
Bson::I32(v) => write!(f, "I32({:?})", v),
Bson::I64(v) => write!(f, "I64({:?})", v),
Bson::TimeStamp(i) => {
let time = (i >> 32) as i32;
let inc = (i & 0xFFFFFFFF) as i32;

write!(f, "TimeStamp({}, {})", time, inc)
}
&Bson::Binary(t, ref vec) => write!(f, "BinData({}, 0x{})", u8::from(t), hex::encode(vec)),
&Bson::ObjectId(ref id) => write!(f, "ObjectId({:?})", id),
&Bson::UtcDatetime(date_time) => write!(f, "UtcDatetime({:?})", date_time),
&Bson::Symbol(ref sym) => write!(f, "Symbol({:?})", sym),
Bson::Binary(t, ref vec) => write!(f, "BinData({}, 0x{})", u8::from(t), hex::encode(vec)),
Bson::ObjectId(ref id) => write!(f, "ObjectId({:?})", id),
Bson::UtcDatetime(date_time) => write!(f, "UtcDatetime({:?})", date_time),
Bson::Symbol(ref sym) => write!(f, "Symbol({:?})", sym),
}
}
}

impl Display for Bson {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
&Bson::FloatingPoint(f) => write!(fmt, "{}", f),
&Bson::String(ref s) => write!(fmt, "\"{}\"", s),
&Bson::Array(ref vec) => {
write!(fmt, "[")?;
match *self {
Bson::FloatingPoint(f) => write!(fmt, "{}", f),
Bson::String(ref s) => write!(fmt, "\"{}\"", s),
Bson::Array(ref vec) => {
fmt.write_str("[")?;

let mut first = true;
for bson in vec.iter() {
for bson in vec {
if !first {
write!(fmt, ", ")?;
fmt.write_str(", ")?;
}

write!(fmt, "{}", bson)?;
first = false;
}

write!(fmt, "]")
fmt.write_str("]")
}
&Bson::Document(ref doc) => write!(fmt, "{}", doc),
&Bson::Boolean(b) => write!(fmt, "{}", b),
&Bson::Null => write!(fmt, "null"),
&Bson::RegExp(ref pat, ref opt) => write!(fmt, "/{}/{}", pat, opt),
&Bson::JavaScriptCode(ref s) | &Bson::JavaScriptCodeWithScope(ref s, _) => fmt.write_str(&s),
&Bson::I32(i) => write!(fmt, "{}", i),
&Bson::I64(i) => write!(fmt, "{}", i),
&Bson::TimeStamp(i) => {
Bson::Document(ref doc) => write!(fmt, "{}", doc),
Bson::Boolean(b) => write!(fmt, "{}", b),
Bson::Null => write!(fmt, "null"),
Bson::RegExp(ref pat, ref opt) => write!(fmt, "/{}/{}", pat, opt),
Bson::JavaScriptCode(ref s) | Bson::JavaScriptCodeWithScope(ref s, _) => fmt.write_str(&s),
Bson::I32(i) => write!(fmt, "{}", i),
Bson::I64(i) => write!(fmt, "{}", i),
Bson::TimeStamp(i) => {
let time = (i >> 32) as i32;
let inc = (i & 0xFFFFFFFF) as i32;

write!(fmt, "Timestamp({}, {})", time, inc)
}
&Bson::Binary(t, ref vec) => write!(fmt, "BinData({}, 0x{})", u8::from(t), hex::encode(vec)),
&Bson::ObjectId(ref id) => write!(fmt, "ObjectId(\"{}\")", id),
&Bson::UtcDatetime(date_time) => write!(fmt, "Date(\"{}\")", date_time),
&Bson::Symbol(ref sym) => write!(fmt, "Symbol(\"{}\")", sym),
Bson::Binary(t, ref vec) => write!(fmt, "BinData({}, 0x{})", u8::from(t), hex::encode(vec)),
Bson::ObjectId(ref id) => write!(fmt, "ObjectId(\"{}\")", id),
Bson::UtcDatetime(date_time) => write!(fmt, "Date(\"{}\")", date_time),
Bson::Symbol(ref sym) => write!(fmt, "Symbol(\"{}\")", sym),
}
}
}
Expand Down Expand Up @@ -205,23 +205,20 @@ impl From<bool> for Bson {
}

impl From<(String, String)> for Bson {
fn from(a: (String, String)) -> Bson {
let (a1, a2) = a;
Bson::RegExp(a1.to_owned(), a2.to_owned())
fn from((pat, opt): (String, String)) -> Bson {
Bson::RegExp(pat, opt)
}
}

impl From<(String, Document)> for Bson {
fn from(a: (String, Document)) -> Bson {
let (a1, a2) = a;
Bson::JavaScriptCodeWithScope(a1, a2)
fn from((code, scope): (String, Document)) -> Bson {
Bson::JavaScriptCodeWithScope(code, scope)
}
}

impl From<(BinarySubtype, Vec<u8>)> for Bson {
fn from(a: (BinarySubtype, Vec<u8>)) -> Bson {
let (a1, a2) = a;
Bson::Binary(a1, a2)
fn from((ty, data): (BinarySubtype, Vec<u8>)) -> Bson {
Bson::Binary(ty, data)
}
}

Expand Down Expand Up @@ -257,7 +254,7 @@ impl From<[u8; 12]> for Bson {

impl From<oid::ObjectId> for Bson {
fn from(a: oid::ObjectId) -> Bson {
Bson::ObjectId(a.to_owned())
Bson::ObjectId(a)
}
}

Expand All @@ -279,16 +276,16 @@ impl From<Value> for Bson {
Value::Bool(x) => x.into(),
Value::Array(x) => Bson::Array(x.into_iter().map(Bson::from).collect()),
Value::Object(x) => {
Bson::from_extended_document(x.into_iter().map(|(k, v)| (k.clone(), v.into())).collect())
Bson::from_extended_document(x.into_iter().map(|(k, v)| (k, v.into())).collect())
}
Value::Null => Bson::Null,
}
}
}

impl Into<Value> for Bson {
fn into(self) -> Value {
match self {
impl From<Bson> for Value {
fn from(bson: Bson) -> Self {
match bson {
Bson::FloatingPoint(v) => json!(v),
Bson::String(v) => json!(v),
Bson::Array(v) => json!(v),
Expand Down Expand Up @@ -336,23 +333,23 @@ impl Into<Value> for Bson {
impl Bson {
/// Get the `ElementType` of this value.
pub fn element_type(&self) -> ElementType {
match self {
&Bson::FloatingPoint(..) => ElementType::FloatingPoint,
&Bson::String(..) => ElementType::Utf8String,
&Bson::Array(..) => ElementType::Array,
&Bson::Document(..) => ElementType::EmbeddedDocument,
&Bson::Boolean(..) => ElementType::Boolean,
&Bson::Null => ElementType::NullValue,
&Bson::RegExp(..) => ElementType::RegularExpression,
&Bson::JavaScriptCode(..) => ElementType::JavaScriptCode,
&Bson::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
&Bson::I32(..) => ElementType::Integer32Bit,
&Bson::I64(..) => ElementType::Integer64Bit,
&Bson::TimeStamp(..) => ElementType::TimeStamp,
&Bson::Binary(..) => ElementType::Binary,
&Bson::ObjectId(..) => ElementType::ObjectId,
&Bson::UtcDatetime(..) => ElementType::UtcDatetime,
&Bson::Symbol(..) => ElementType::Symbol,
match *self {
Bson::FloatingPoint(..) => ElementType::FloatingPoint,
Bson::String(..) => ElementType::Utf8String,
Bson::Array(..) => ElementType::Array,
Bson::Document(..) => ElementType::EmbeddedDocument,
Bson::Boolean(..) => ElementType::Boolean,
Bson::Null => ElementType::NullValue,
Bson::RegExp(..) => ElementType::RegularExpression,
Bson::JavaScriptCode(..) => ElementType::JavaScriptCode,
Bson::JavaScriptCodeWithScope(..) => ElementType::JavaScriptCodeWithScope,
Bson::I32(..) => ElementType::Integer32Bit,
Bson::I64(..) => ElementType::Integer64Bit,
Bson::TimeStamp(..) => ElementType::TimeStamp,
Bson::Binary(..) => ElementType::Binary,
Bson::ObjectId(..) => ElementType::ObjectId,
Bson::UtcDatetime(..) => ElementType::UtcDatetime,
Bson::Symbol(..) => ElementType::Symbol,
}
}

Expand Down Expand Up @@ -437,7 +434,7 @@ impl Bson {
}

/// Converts from extended format.
/// This function mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
/// This function is mainly used for [extended JSON format](https://docs.mongodb.com/manual/reference/mongodb-extended-json/).
#[doc(hidden)]
pub fn from_extended_document(values: Document) -> Bson {
if values.len() == 2 {
Expand Down Expand Up @@ -478,7 +475,7 @@ impl Bson {
/// If `Bson` is `FloatingPoint`, return its value. Returns `None` otherwise
pub fn as_f64(&self) -> Option<f64> {
match *self {
Bson::FloatingPoint(ref v) => Some(*v),
Bson::FloatingPoint(v) => Some(v),
_ => None,
}
}
Expand Down Expand Up @@ -510,23 +507,23 @@ impl Bson {
/// If `Bson` is `Boolean`, return its value. Returns `None` otherwise
pub fn as_bool(&self) -> Option<bool> {
match *self {
Bson::Boolean(ref v) => Some(*v),
Bson::Boolean(v) => Some(v),
_ => None,
}
}

/// If `Bson` is `I32`, return its value. Returns `None` otherwise
pub fn as_i32(&self) -> Option<i32> {
match *self {
Bson::I32(ref v) => Some(*v),
Bson::I32(v) => Some(v),
_ => None,
}
}

/// If `Bson` is `I64`, return its value. Returns `None` otherwise
pub fn as_i64(&self) -> Option<i64> {
match *self {
Bson::I64(ref v) => Some(*v),
Bson::I64(v) => Some(v),
_ => None,
}
}
Expand Down Expand Up @@ -558,7 +555,7 @@ impl Bson {
/// If `Bson` is `TimeStamp`, return its value. Returns `None` otherwise
pub fn as_timestamp(&self) -> Option<i64> {
match *self {
Bson::TimeStamp(ref v) => Some(*v),
Bson::TimeStamp(v) => Some(v),
_ => None,
}
}
Expand Down Expand Up @@ -587,7 +584,7 @@ impl Bson {
/// timestamp: TimeStamp,
/// }
/// ```
#[derive(Debug, Eq, PartialEq, Clone)]
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
pub struct TimeStamp {
pub t: u32,
pub i: u32,
Expand Down
2 changes: 1 addition & 1 deletion src/decoder/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl fmt::Display for DecoderError {
DecoderError::ExpectedField(field_type) => write!(fmt, "expected a field of type `{}`", field_type),
DecoderError::UnknownField(ref field) => write!(fmt, "unknown field `{}`", field),
DecoderError::SyntaxError(ref inner) => inner.fmt(fmt),
DecoderError::EndOfStream => write!(fmt, "end of stream"),
DecoderError::EndOfStream => fmt.write_str("end of stream"),
DecoderError::InvalidType(ref desc) => desc.fmt(fmt),
DecoderError::InvalidLength(ref len, ref desc) => write!(fmt, "expecting length {}, {}", len, desc),
DecoderError::DuplicatedField(ref field) => write!(fmt, "duplicated field `{}`", field),
Expand Down
2 changes: 1 addition & 1 deletion src/decoder/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl<'de> Visitor<'de> for BsonVisitor {
type Value = Bson;

fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "expecting a Bson")
f.write_str("expecting a Bson")
}

#[inline]
Expand Down
37 changes: 18 additions & 19 deletions src/encoder/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,33 @@ impl From<io::Error> for EncoderError {

impl fmt::Display for EncoderError {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self {
&EncoderError::IoError(ref inner) => inner.fmt(fmt),
&EncoderError::InvalidMapKeyType(ref bson) => write!(fmt, "Invalid map key type: {:?}", bson),
&EncoderError::Unknown(ref inner) => inner.fmt(fmt),
&EncoderError::UnsupportedUnsignedType => write!(fmt, "BSON does not support unsigned type"),
&EncoderError::UnsignedTypesValueExceedsRange(value) => {
write!(
fmt,
"BSON does not support unsigned types.
An attempt to encode the value: {} in a signed type failed due to the values size.",
value
)
},
match *self {
EncoderError::IoError(ref inner) => inner.fmt(fmt),
EncoderError::InvalidMapKeyType(ref bson) => write!(fmt, "Invalid map key type: {:?}", bson),
EncoderError::Unknown(ref inner) => inner.fmt(fmt),
EncoderError::UnsupportedUnsignedType => fmt.write_str("BSON does not support unsigned type"),
EncoderError::UnsignedTypesValueExceedsRange(value) => write!(
fmt,
"BSON does not support unsigned types.
An attempt to encode the value: {} in a signed type failed due to the value's size.",
value
),
}
}
}

impl error::Error for EncoderError {
fn description(&self) -> &str {
match self {
&EncoderError::IoError(ref inner) => inner.description(),
&EncoderError::InvalidMapKeyType(_) => "Invalid map key type",
&EncoderError::Unknown(ref inner) => inner,
&EncoderError::UnsupportedUnsignedType => "BSON does not support unsigned type",
&EncoderError::UnsignedTypesValueExceedsRange(_) => "BSON does not support unsigned types.
match *self {
EncoderError::IoError(ref inner) => inner.description(),
EncoderError::InvalidMapKeyType(_) => "Invalid map key type",
EncoderError::Unknown(ref inner) => inner,
EncoderError::UnsupportedUnsignedType => "BSON does not support unsigned type",
EncoderError::UnsignedTypesValueExceedsRange(_) => "BSON does not support unsigned types.
An attempt to encode the value: {} in a signed type failed due to the values size."
}
}

fn cause(&self) -> Option<&error::Error> {
match self {
&EncoderError::IoError(ref inner) => Some(inner),
Expand Down
34 changes: 17 additions & 17 deletions src/encoder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,37 +102,37 @@ fn encode_bson<W: Write + ?Sized>(writer: &mut W, key: &str, val: &Bson) -> Enco
writer.write_u8(val.element_type() as u8)?;
write_cstring(writer, key)?;

match val {
&Bson::FloatingPoint(v) => write_f64(writer, v),
&Bson::String(ref v) => write_string(writer, &v),
&Bson::Array(ref v) => encode_array(writer, &v),
&Bson::Document(ref v) => encode_document(writer, v),
&Bson::Boolean(v) => writer.write_u8(if v { 0x01 } else { 0x00 }).map_err(From::from),
&Bson::RegExp(ref pat, ref opt) => {
match *val {
Bson::FloatingPoint(v) => write_f64(writer, v),
Bson::String(ref v) => write_string(writer, &v),
Bson::Array(ref v) => encode_array(writer, &v),
Bson::Document(ref v) => encode_document(writer, v),
Bson::Boolean(v) => writer.write_u8(if v { 0x01 } else { 0x00 }).map_err(From::from),
Bson::RegExp(ref pat, ref opt) => {
write_cstring(writer, pat)?;
write_cstring(writer, opt)
}
&Bson::JavaScriptCode(ref code) => write_string(writer, &code),
&Bson::ObjectId(ref id) => writer.write_all(&id.bytes()).map_err(From::from),
&Bson::JavaScriptCodeWithScope(ref code, ref scope) => {
Bson::JavaScriptCode(ref code) => write_string(writer, &code),
Bson::ObjectId(ref id) => writer.write_all(&id.bytes()).map_err(From::from),
Bson::JavaScriptCodeWithScope(ref code, ref scope) => {
let mut buf = Vec::new();
write_string(&mut buf, code)?;
encode_document(&mut buf, scope)?;

write_i32(writer, buf.len() as i32 + 4)?;
writer.write_all(&buf).map_err(From::from)
}
&Bson::I32(v) => write_i32(writer, v),
&Bson::I64(v) => write_i64(writer, v),
&Bson::TimeStamp(v) => write_i64(writer, v),
&Bson::Binary(subtype, ref data) => {
Bson::I32(v) => write_i32(writer, v),
Bson::I64(v) => write_i64(writer, v),
Bson::TimeStamp(v) => write_i64(writer, v),
Bson::Binary(subtype, ref data) => {
write_i32(writer, data.len() as i32)?;
writer.write_u8(From::from(subtype))?;
writer.write_all(data).map_err(From::from)
}
&Bson::UtcDatetime(ref v) => write_i64(writer, (v.timestamp() * 1000) + (v.nanosecond() / 1_000_000) as i64),
&Bson::Null => Ok(()),
&Bson::Symbol(ref v) => write_string(writer, &v),
Bson::UtcDatetime(ref v) => write_i64(writer, (v.timestamp() * 1000) + (v.nanosecond() / 1_000_000) as i64),
Bson::Null => Ok(()),
Bson::Symbol(ref v) => write_string(writer, &v),
}
}

Expand Down
Loading