Build status Crate version License: MIT Rust Docs

derive for crate unhtml Crate version


Table of Contents

Derive Target

struct

Basic Usage

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

[html(selector = "#test")]

struct SingleUser { #[html(selector = "p:nth-child(1)", attr = "inner")] name: String,

#[html(selector = "p:nth-child(2)", attr = "inner")]
age: u8,

#[html(selector = "p:nth-child(3)", attr = "inner")]
like_lemon: bool,

}

let user = SingleUser::fromhtml(r#" Title

Hexilee

20

true

"#).unwrap(); asserteq!("Hexilee", &user.name); asserteq!(20, user.age); assert!(user.likelemon); ```

Attributes

html

target

derive target or field

specification

#[html(selector = "...", attr = "...", default = ...)]

selector, attr, default or html itself can be unnecessary.

This is valid

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct SingleString { value: String, } ```

selector

target

derive target or field

literal type

string

specification

selector must be a valid css-selector, invalid selector will cause a compile-time panic

```rust,should_panic // panic

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

[html(selector = "<>")]

struct SingleUser {} ```

```rust,should_panic // panic

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::*;

[derive(FromHtml)]

struct SingleUser { #[html(selector = "<>", attr = "inner")] name: String, } ```

if multi element is selected and field type is not Vec, the first will be chosen

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

[html(selector = "a")]

struct Link { #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

}

let link = Link::fromhtml(r#" Github Google "#).unwrap(); asserteq!("https://github.com", &link.href); assert_eq!("Github", &link.value); ```

default behavior

html of its root element

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

}

let link = Link::fromhtml(r#"Github"#).unwrap(); asserteq!("https://github.com", &link.href); assert_eq!("Github", &link.value); ```

attr

target

field

literal type

string

specification

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

}

let link = Link::fromhtml(r#"Github"#).unwrap(); asserteq!("https://github.com", &link.href); assert_eq!("Github", &link.value); ```

default behavior

html of the whole element (not innerHtml!)

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

source: String,

}

let link = Link::fromhtml(r#"Github"#).unwrap(); asserteq!("https://github.com", &link.href); asserteq!("Github", &link.value); asserteq!(r#"Github"#, &link.source); ```

default

target

field

literal type

any literal type

specification

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct DefaultUser { // invoke String::from_html #[html(selector = "#non-exist", default = "Hexilee")] name: String,

// invoke u8::from<u8>
#[html(default = 20)]
age: u8,

#[html(default = true)]
like_lemon: bool,

}

let user = DefaultUser::fromhtml("

").unwrap(); asserteq!("Hexilee", &user.name); asserteq!(20, user.age); asserteq!(-1000, user.assets); assert!(user.like_lemon); ```

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

}

[derive(FromHtml)]

struct Website { #[html(default = "10")] age: u8,

#[html(default = "<a href='https://github.com'>Github</a>")]
link: Link,

}

let website = Website::fromhtml("

").unwrap(); let link = website.link; asserteq!(10u8, website.age); asserteq!("https://github.com", &link.href); asserteq!("Github", &link.value); ```

default behavior

return a Err(unhtml::failure::Error) when selected nothing

```rust,should_panic // panic

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { // no default #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

}

let link = Link::from_html(r#"Github"#).unwrap(); ```

Field Type

any sized path type, without generics

```rust,should_panic // panic

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { // no default #[html(attr = "href")] href: &str, } ```

```rust,should_panic // panic

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Website { // no default #[html(attr = "href")] hrefs: std::collections::LinkedList, } ```

```rust,should_panic // panic

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Website { // no default #[html(attr = "href")] hrefs: [String], } ```

Vec

Should use unhtml::VecFromHtml

```rust extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml, VecFromHtml};

[derive(FromHtml)]

struct TestUser { #[html(selector = "p:nth-child(1)", attr = "inner")] name: String,

#[html(selector = "p:nth-child(2)", attr = "inner")]
age: u8,

#[html(selector = "p:nth-child(3)", attr = "inner")]
like_lemon: bool,

}

[derive(FromHtml)]

[html(selector = "#test")]

struct TestUsers { #[html(selector = "div")] users: Vec, }

let users = TestUsers::fromhtml(r#" Title

Hexilee

20

true

BigBrother

21

false

"#).unwrap(); let hexilee = &users.users[0]; let bigbrother = &users.users[1]; asserteq!("Hexilee", &hexilee.name); asserteq!(20, hexilee.age); assert!(hexilee.likelemon); asserteq!("BigBrother", &bigbrother.name); asserteq!(21, bigbrother.age); assert!(!bigbrother.like_lemon); ```

as the documentation of crate unhtml, if you want Vec<TestUser> straightly, you can just:

```rust extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, VecFromHtml};

[derive(FromHtml)]

struct TestUser { #[html(selector = "p:nth-child(1)", attr = "inner")] name: String,

#[html(selector = "p:nth-child(2)", attr = "inner")]
age: u8,

#[html(selector = "p:nth-child(3)", attr = "inner")]
like_lemon: bool,

}

let users = Vec::::fromhtml("#test > div", r#" Title

Hexilee

20

true

BigBrother

21

false

"#).unwrap(); let hexilee = &users[0]; let bigbrother = &users[1]; asserteq!("Hexilee", &hexilee.name); asserteq!(20, hexilee.age); assert!(hexilee.likelemon); asserteq!("BigBrother", &bigbrother.name); asserteq!(21, bigbrother.age); assert!(!bigbrother.like_lemon); ```

Source HTML

with top selector

all source html will be parsed as fragment. The top element is html and there is no DOCTYPE, head or body.

html,ignore <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="test"> <div> <p>Hexilee</p> <p>20</p> <p>true</p> </div> </div> </body> </html>

will be parsed as:

html,ignore <html lang="en"> <meta charset="UTF-8"> <title>Title</title> <div id="test"> <div> <p>Hexilee</p> <p>20</p> <p>true</p> </div> </div> </html>

and

```html,ignore

Hexilee

```

will be parsed as:

html,ignore <html> <p>Hexilee</p> </html>

```rust,should_panic

// panic

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Document { // no default #[html(selector = "head")] head: String,

#[html(selector = "body")]
body: String,

}

let dicument = Document::from_html(r#" Title

Hexilee

20

true

"#).unwrap(); ```

without top selector

when derived struct doesn't have top selector, all source html will be parsed as pure fragment. There is no DOCTYPE, html, head or body.

html,ignore <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="test"> <div> <p>Hexilee</p> <p>20</p> <p>true</p> </div> </div> </body> </html>

will be parsed as:

```html,ignore Title

Hexilee

20

true

```

and

```html,ignore

Hexilee

```

will be parsed as:

```html,ignore

Hexilee

```

```rust

[macro_use]

extern crate unhtml_derive; extern crate unhtml; use unhtml::{self, FromHtml};

[derive(FromHtml)]

struct Link { #[html(attr = "href")] href: String,

#[html(attr = "inner")]
value: String,

}

let link = Link::fromhtml(r#"Github"#).unwrap(); asserteq!("https://github.com", &link.href); assert_eq!("Github", &link.value); ```