diff --git a/Cargo.lock b/Cargo.lock index 622a082..b5ac8fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,6 +172,16 @@ dependencies = [ "dtoa", ] +[[package]] +name = "duplicate" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0a4be4cd710e92098de6ad258e6e7c24af11c29c5142f3c6f2a545652480ff8" +dependencies = [ + "heck", + "proc-macro-error", +] + [[package]] name = "ego-tree" version = "0.6.2" @@ -250,6 +260,12 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "html5ever" version = "0.26.0" @@ -533,6 +549,30 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -854,6 +894,7 @@ name = "tildes-parser" version = "0.1.0" dependencies = [ "color-eyre", + "duplicate", "insta", "lazy_static", "regex", @@ -926,6 +967,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index efe1cfa..b33b867 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ path = "source/lib.rs" [dependencies] color-eyre = "^0.6.2" +duplicate = "^0.4.1" lazy_static = "^1.4.0" regex = "^1.6.0" scraper = "^0.13.0" diff --git a/source/from_str.rs b/source/from_str.rs new file mode 100644 index 0000000..ef2b674 --- /dev/null +++ b/source/from_str.rs @@ -0,0 +1,21 @@ +//! Implements [`FromStr`] for parser structs. + +use std::str::FromStr; + +use {color_eyre::eyre::Error, duplicate::duplicate_item, scraper::Html}; + +use crate::{Group, GroupList}; + +#[duplicate_item( + _Struct; + [Group]; + [GroupList]; +)] +impl FromStr for _Struct { + type Err = Error; + + fn from_str(s: &str) -> Result { + let html = Html::parse_document(s); + _Struct::from_html(&html) + } +} diff --git a/source/group.rs b/source/group.rs index e70439b..144c1a8 100644 --- a/source/group.rs +++ b/source/group.rs @@ -1,11 +1,6 @@ //! Parsing for `/~`. -use std::str::FromStr; - -use { - color_eyre::{eyre::Error, Result}, - scraper::Html, -}; +use {color_eyre::Result, scraper::Html}; use crate::{ regexes::GROUP_SUBSCRIBERS_RE, @@ -47,15 +42,6 @@ pub struct GroupWikiLink { pub url: String, } -impl FromStr for Group { - type Err = Error; - - fn from_str(s: &str) -> Result { - let html = Html::parse_document(s); - Self::from_html(&html) - } -} - impl Group { /// Parses a [`Group`] from a [`scraper::Html`] tree. pub fn from_html(html: &Html) -> Result { diff --git a/source/group_list.rs b/source/group_list.rs index 5a126dc..6890b61 100644 --- a/source/group_list.rs +++ b/source/group_list.rs @@ -1,11 +1,6 @@ //! Parsing for [`/groups`](https://tildes.net/groups). -use std::str::FromStr; - -use { - color_eyre::{eyre::Error, Result}, - scraper::Html, -}; +use {color_eyre::Result, scraper::Html}; use crate::{ regexes::{DUPLICATE_WHITESPACE_RE, GROUP_LIST_ACTIVITY_RE}, @@ -37,15 +32,6 @@ pub struct GroupListSummary { pub topic_activity: Option, } -impl FromStr for GroupList { - type Err = Error; - - fn from_str(s: &str) -> Result { - let html = Html::parse_document(s); - Self::from_html(&html) - } -} - impl GroupList { /// Parses a [`GroupList`] from a [`scraper::Html`] tree. pub fn from_html(html: &Html) -> Result { diff --git a/source/lib.rs b/source/lib.rs index fc650f0..676e1bd 100644 --- a/source/lib.rs +++ b/source/lib.rs @@ -24,6 +24,7 @@ pub mod regexes; pub mod selectors; pub mod utilities; +pub(crate) mod from_str; pub(crate) mod group; pub(crate) mod group_list;