Skip to content

Commit

Permalink
Merge pull request #48 from casey/readme-doctest
Browse files Browse the repository at this point in the history
Use `doc-comment` crate to run readme doctests
  • Loading branch information
thequux committed May 20, 2021
2 parents 79ce71f + d3bc57e commit cf1e618
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 497 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ codegen-units = 1
### DEPENDENCIES ###############################################################

[dependencies]
rustversion = "1.0.4"
serde_ = { version = "^1.0" , optional = true, package = "serde" }
serde_bytes = { version = "^0.11.3", optional = true }
snafu = { version = "^0.6.9", default_features = false }

[dev-dependencies]
doc-comment = "0.3.3"
regex = "^1.0"
serde_derive = "^1.0"

Expand Down
213 changes: 82 additions & 131 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,12 @@ it is enough to import the trait and call the `to_bencode()` function on the obj
```rust
use bendy::encoding::{ToBencode, Error};

fn main() {}
let my_data = vec!["hello", "world"];
let encoded = my_data.to_bencode()?;

#[test]
fn encode_vector() -> Result<(), Error> {
let my_data = vec!["hello", "world"];
let encoded = my_data.to_bencode()?;
assert_eq!(b"l5:hello5:worlde", encoded.as_slice());

assert_eq!(b"l5:hello5:worlde", encoded.as_slice());
Ok(())
}
Ok::<(), Error>(())
```

### Implementing `ToBencode`
Expand Down Expand Up @@ -140,20 +136,15 @@ impl ToBencode for IntegerWrapper {
}
}

fn main() {}

#[test]
fn encode_integer() -> Result<(), Error> {
let example = IntegerWrapper(21);
let example = IntegerWrapper(21);

let encoded = example.to_bencode()?;
assert_eq!(b"i21e", encoded.as_slice());
let encoded = example.to_bencode()?;
assert_eq!(b"i21e", encoded.as_slice());

let encoded = 21.to_bencode()?;
assert_eq!(b"i21e", encoded.as_slice());
let encoded = 21.to_bencode()?;
assert_eq!(b"i21e", encoded.as_slice());

Ok(())
}
Ok::<(), Error>(())
```

**Encode a byte string**
Expand All @@ -174,20 +165,15 @@ impl ToBencode for StringWrapper {
}
}

fn main() {}

#[test]
fn encode_string() -> Result<(), Error> {
let example = StringWrapper("content".to_string());
let example = StringWrapper("content".to_string());

let encoded = example.to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());
let encoded = example.to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());

let encoded = "content".to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());
let encoded = "content".to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());

Ok(())
}
Ok::<(), Error>(())
```

As its a very common pattern to represent a byte string as `Vec<u8>` bendy
Expand All @@ -209,20 +195,15 @@ impl ToBencode for ByteStringWrapper {
}
}

fn main() {}

#[test]
fn encode_byte_string() -> Result<(), Error> {
let example = ByteStringWrapper(b"content".to_vec());
let example = ByteStringWrapper(b"content".to_vec());

let encoded = example.to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());
let encoded = example.to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());

let encoded = AsString(b"content").to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());
let encoded = AsString(b"content").to_bencode()?;
assert_eq!(b"7:content", encoded.as_slice());

Ok(())
}
Ok::<(), Error>(())
```

**Encode a dictionary**
Expand Down Expand Up @@ -258,17 +239,12 @@ impl ToBencode for Example {
}
}

fn main() {}

#[test]
fn encode_dictionary() -> Result<(), Error> {
let example = Example { label: "Example".to_string(), counter: 0 };
let example = Example { label: "Example".to_string(), counter: 0 };

let encoded = example.to_bencode()?;
assert_eq!(b"d7:counteri0e5:label7:Examplee", encoded.as_slice());
let encoded = example.to_bencode()?;
assert_eq!(b"d7:counteri0e5:label7:Examplee", encoded.as_slice());

Ok(())
}
Ok::<(), Error>(())
```

**Encode a list**
Expand All @@ -293,17 +269,12 @@ impl ToBencode for Location {
}
}

fn main() {}

#[test]
fn encode_list() -> Result<(), Error> {
let example = Location(2, 3);
let example = Location(2, 3);

let encoded = example.to_bencode()?;
assert_eq!(b"li2ei3ee", encoded.as_slice());
let encoded = example.to_bencode()?;
assert_eq!(b"li2ei3ee", encoded.as_slice());

Ok(())
}
Ok::<(), Error>(())
```

### Decoding with `FromBencode`
Expand All @@ -314,17 +285,12 @@ it is enough to import the trait and call the `from_bencode()` function on the o
```rust
use bendy::decoding::{FromBencode, Error};

fn main() {}
let encoded = b"l5:hello5:worlde".to_vec();
let decoded = Vec::<String>::from_bencode(&encoded)?;

#[test]
fn decode_vector() -> Result<(), Error> {
let encoded = b"l5:hello5:worlde".to_vec();
let decoded = Vec::<String>::from_bencode(&encoded)?;

assert_eq!(vec!["hello", "world"], decoded);
Ok(())
}
assert_eq!(vec!["hello", "world"], decoded);

Ok::<(), Error>(())
```

### Implementing `FromBencode`
Expand Down Expand Up @@ -373,20 +339,15 @@ impl FromBencode for IntegerWrapper {
}
}

fn main() {}

#[test]
fn decode_integer() -> Result<(), Error> {
let encoded = b"i21e".to_vec();
let encoded = b"i21e".to_vec();

let example = IntegerWrapper::from_bencode(&encoded)?;
assert_eq!(IntegerWrapper(21), example);
let example = IntegerWrapper::from_bencode(&encoded)?;
assert_eq!(IntegerWrapper(21), example);

let example = i64::from_bencode(&encoded)?;
assert_eq!(21, example);
let example = i64::from_bencode(&encoded)?;
assert_eq!(21, example);

Ok(())
}
Ok::<(), Error>(())
```

**Decode a byte string**
Expand Down Expand Up @@ -414,20 +375,15 @@ impl FromBencode for StringWrapper {
}
}

fn main() {}
let encoded = b"7:content".to_vec();

#[test]
fn decode_string() -> Result<(), Error> {
let encoded = b"7:content".to_vec();
let example = StringWrapper::from_bencode(&encoded)?;
assert_eq!(StringWrapper("content".to_string()), example);

let example = StringWrapper::from_bencode(&encoded)?;
assert_eq!(StringWrapper("content".to_string()), example);
let example = String::from_bencode(&encoded)?;
assert_eq!("content".to_string(), example);

let example = String::from_bencode(&encoded)?;
assert_eq!("content".to_string(), example);

Ok(())
}
Ok::<(), Error>(())
```

If the content is a non utf8 encoded string or an actual byte sequence the
Expand All @@ -452,20 +408,15 @@ impl FromBencode for ByteStringWrapper {
}
}

fn main() {}
let encoded = b"7:content".to_vec();

#[test]
fn decode_byte_string() -> Result<(), Error> {
let encoded = b"7:content".to_vec();
let example = ByteStringWrapper::from_bencode(&encoded)?;
assert_eq!(ByteStringWrapper(b"content".to_vec()), example);

let example = ByteStringWrapper::from_bencode(&encoded)?;
assert_eq!(ByteStringWrapper(b"content".to_vec()), example);
let example = AsString::from_bencode(&encoded)?;
assert_eq!(b"content".to_vec(), example.0);

let example = AsString::from_bencode(&encoded)?;
assert_eq!(b"content".to_vec(), example.0);

Ok(())
}
Ok::<(), Error>(())
```

**Decode a dictionary**
Expand Down Expand Up @@ -522,18 +473,13 @@ impl FromBencode for Example {
}
}

fn main() {}
let encoded = b"d7:counteri0e5:label7:Examplee".to_vec();
let expected = Example { label: "Example".to_string(), counter: 0 };

#[test]
fn decode_dictionary() -> Result<(), Error> {
let encoded = b"d7:counteri0e5:label7:Examplee".to_vec();
let expected = Example { label: "Example".to_string(), counter: 0 };
let example = Example::from_bencode(&encoded)?;
assert_eq!(expected, example);

let example = Example::from_bencode(&encoded)?;
assert_eq!(expected, example);

Ok(())
}
Ok::<(), Error>(())
```

**Decode a list**
Expand Down Expand Up @@ -563,18 +509,13 @@ impl FromBencode for Location {
}
}

fn main() {}
let encoded = b"li2ei3ee".to_vec();
let expected = Location(2, 3);

#[test]
fn decode_list() -> Result<(), Error> {
let encoded = b"li2ei3ee".to_vec();
let expected = Location(2, 3);
let example = Location::from_bencode(&encoded)?;
assert_eq!(expected, example);

let example = Location::from_bencode(&encoded)?;
assert_eq!(expected, example);

Ok(())
}
Ok::<(), Error>(())
```

### Optional: Limitation of recursive parsing
Expand Down Expand Up @@ -617,22 +558,32 @@ respectively:


```rust
use serde::{Deserialize, Serialize};
# #[cfg(not(feature = "serde"))]
# fn main() {}
# #[cfg(feature = "serde")]
# fn main() -> Result<(), bendy::serde::Error> {

use serde_derive::{Deserialize, Serialize};

#[serde(crate = "serde_")]
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Foo {
bar: String,
}

fn main() {
let value = Foo {
bar: "hello".into(),
};
let bencode = bendy::serde::to_bytes(&value).unwrap();
assert_eq!(bencode, b"d3:bar5:helloe");
let deserialized = bendy::serde::from_bytes::<Foo>(&bencode).unwrap();
assert_eq!(deserialized, value);
}
let value = Foo {
bar: "hello".into(),
};

let bencode = bendy::serde::to_bytes(&value)?;
assert_eq!(bencode, b"d3:bar5:helloe");

let deserialized = bendy::serde::from_bytes::<Foo>(&bencode)?;
assert_eq!(deserialized, value);

Ok(())

# }
```

Information on how Rust types are represented in bencode is available in the
Expand Down
1 change: 0 additions & 1 deletion rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
unstable_features = true

required_version = "1.4.26"
edition = "2018"

format_code_in_doc_comments = true
Expand Down
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ pub mod state_tracker;
pub mod serde;

pub mod value;

#[rustversion::since(1.40)]
const _: () = {
#[cfg(doctest)]
doc_comment::doctest!("../README.md");
};
Loading

0 comments on commit cf1e618

Please sign in to comment.