From 5698cb2bcba9b68e512591106c81d4d93fc596b7 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 5 May 2023 16:58:48 +0300 Subject: [PATCH] core: add doc examples --- Makefile | 4 + core/src/connection.rs | 35 ++++++++ core/src/doctests/db_setup.rs.inc | 52 ++++++++++++ core/src/models.rs | 137 +++++++++++++++++++++++++----- 4 files changed, 209 insertions(+), 19 deletions(-) create mode 100644 core/src/doctests/db_setup.rs.inc diff --git a/Makefile b/Makefile index 54adb8b..30457cd 100644 --- a/Makefile +++ b/Makefile @@ -25,3 +25,7 @@ test: check lint .PHONY: rustdoc rustdoc: @RUSTDOCFLAGS="--html-before-content ./.github/doc_extra.html" cargo doc --workspace --all-features --no-deps --document-private-items + +.PHONY: rustdoc-open +rustdoc-open: + @RUSTDOCFLAGS="--html-before-content ./.github/doc_extra.html" cargo doc --workspace --all-features --no-deps --document-private-items --open diff --git a/core/src/connection.rs b/core/src/connection.rs index 235e878..7d3e619 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -138,6 +138,41 @@ impl Connection { /// `Connection` supports a limited subset of operations by default (see /// [`Connection::untrusted`]). /// Use [`Connection::trusted`] to remove these limits. + /// + /// # Example + /// + /// ```rust + /// use mailpot::{Connection, Configuration}; + /// use melib::smtp::{SmtpServerConf, SmtpAuth, SmtpSecurity}; + /// # + /// # fn main() -> mailpot::Result<()> { + /// # use tempfile::TempDir; + /// # + /// # let tmp_dir = TempDir::new()?; + /// # let db_path = tmp_dir.path().join("mpot.db"); + /// # let data_path = tmp_dir.path().to_path_buf(); + /// let config = Configuration { + /// send_mail: mailpot::SendMail::Smtp( + /// SmtpServerConf { + /// hostname: "127.0.0.1".into(), + /// port: 25, + /// envelope_from: "foo-chat@example.com".into(), + /// auth: SmtpAuth::None, + /// security: SmtpSecurity::None, + /// extensions: Default::default(), + /// } + /// ), + /// db_path, + /// data_path, + /// administrators: vec![], + /// }; + /// # assert_eq!(&Connection::open_db(config.clone()).unwrap_err().to_string(), "Database doesn't exist"); + /// + /// let db = Connection::open_or_create_db(config)?; + /// # _ = db; + /// # Ok(()) + /// # } + /// ``` pub fn open_db(conf: Configuration) -> Result { use std::sync::Once; diff --git a/core/src/doctests/db_setup.rs.inc b/core/src/doctests/db_setup.rs.inc new file mode 100644 index 0000000..bb38811 --- /dev/null +++ b/core/src/doctests/db_setup.rs.inc @@ -0,0 +1,52 @@ +# use mailpot::{*, models::*}; +# use melib::smtp::{SmtpServerConf, SmtpAuth, SmtpSecurity}; +# +# use tempfile::TempDir; +# +# let tmp_dir = TempDir::new()?; +# let db_path = tmp_dir.path().join("mpot.db"); +# let data_path = tmp_dir.path().to_path_buf(); +# let config = Configuration { +# send_mail: mailpot::SendMail::Smtp( +# SmtpServerConf { +# hostname: "127.0.0.1".into(), +# port: 25, +# envelope_from: "foo-chat@example.com".into(), +# auth: SmtpAuth::None, +# security: SmtpSecurity::None, +# extensions: Default::default(), +# } +# ), +# db_path, +# data_path, +# administrators: vec![], +# }; +# let db = Connection::open_or_create_db(config)?.trusted(); +# let list = db +# .create_list(MailingList { +# pk: 5, +# name: "foobar chat".into(), +# id: "foo-chat".into(), +# address: "foo-chat@example.com".into(), +# description: Some("Hello world, from foo-chat list".into()), +# archive_url: Some("https://lists.example.com".into()), +# }) +# .unwrap(); +# let sub_policy = SubscriptionPolicy { +# pk: 1, +# list: 5, +# send_confirmation: true, +# open: false, +# manual: false, +# request: true, +# custom: false, +# }; +# let post_policy = PostPolicy { +# pk: 1, +# list: 5, +# announce_only: false, +# subscription_only: false, +# approval_needed: false, +# open: true, +# custom: false, +# }; diff --git a/core/src/models.rs b/core/src/models.rs index d743829..fbac235 100644 --- a/core/src/models.rs +++ b/core/src/models.rs @@ -28,6 +28,18 @@ use std::borrow::Cow; use melib::email::Address; /// A database entry and its primary key. Derefs to its inner type. +/// +/// # Example +/// +/// ```rust,no_run +/// # use mailpot::{*, models::*}; +/// # fn foo(db: &Connection) { +/// let val: Option> = db.list(5).unwrap(); +/// if let Some(list) = val { +/// assert_eq!(list.pk(), 5); +/// } +/// # } +/// ``` #[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize)] #[serde(transparent)] pub struct DbVal(pub T, #[serde(skip)] pub i64); @@ -105,13 +117,34 @@ impl std::fmt::Display for MailingList { } impl MailingList { - /// Mailing list display name (e.g. `list name `). + /// Mailing list display name. + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!( + /// &list.display_name(), + /// "\"foobar chat\" " + /// ); + /// # Ok(()) + /// # } pub fn display_name(&self) -> String { format!("\"{}\" <{}>", self.name, self.address) } #[inline] /// Request subaddress. + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!(&list.request_subaddr(), "foo-chat+request@example.com"); + /// # Ok(()) + /// # } pub fn request_subaddr(&self) -> String { let p = self.address.split('@').collect::>(); format!("{}+request@{}", p[0], p[1]) @@ -120,6 +153,17 @@ impl MailingList { /// Value of `List-Id` header. /// /// See RFC2919 Section 3: + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!( + /// &list.id_header(), + /// "Hello world, from foo-chat list "); + /// # Ok(()) + /// # } pub fn id_header(&self) -> String { let p = self.address.split('@').collect::>(); format!( @@ -134,6 +178,18 @@ impl MailingList { /// Value of `List-Help` header. /// /// See RFC2369 Section 3.1: + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!( + /// &list.help_header().unwrap(), + /// "" + /// ); + /// # Ok(()) + /// # } pub fn help_header(&self) -> Option { Some(format!("", self.request_subaddr())) } @@ -141,6 +197,19 @@ impl MailingList { /// Value of `List-Post` header. /// /// See RFC2369 Section 3.4: + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!(&list.post_header(None).unwrap(), "NO"); + /// assert_eq!( + /// &list.post_header(Some(&post_policy)).unwrap(), + /// "" + /// ); + /// # Ok(()) + /// # } pub fn post_header(&self, policy: Option<&PostPolicy>) -> Option { Some(policy.map_or_else( || "NO".to_string(), @@ -157,18 +226,26 @@ impl MailingList { /// Value of `List-Unsubscribe` header. /// /// See RFC2369 Section 3.2: + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!( + /// &list.unsubscribe_header(Some(&sub_policy)).unwrap(), + /// "" + /// ); + /// # Ok(()) + /// # } pub fn unsubscribe_header(&self, policy: Option<&SubscriptionPolicy>) -> Option { policy.map_or_else( || None, - |p| { - if p.open { - None - } else { - Some(format!( - "", - self.request_subaddr() - )) - } + |_| { + Some(format!( + "", + self.request_subaddr() + )) }, ) } @@ -176,18 +253,27 @@ impl MailingList { /// Value of `List-Subscribe` header. /// /// See RFC2369 Section 3.3: + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!( + /// &list.subscribe_header(Some(&sub_policy)).unwrap(), + /// "", + /// ); + /// # Ok(()) + /// # } + /// ``` pub fn subscribe_header(&self, policy: Option<&SubscriptionPolicy>) -> Option { policy.map_or_else( || None, - |p| { - if p.open { - None - } else { - Some(format!( - "", - self.request_subaddr() - )) - } + |_| { + Some(format!( + "", + self.request_subaddr() + )) }, ) } @@ -195,6 +281,19 @@ impl MailingList { /// Value of `List-Archive` header. /// /// See RFC2369 Section 3.6: + /// + /// # Example + /// + /// ```rust + /// # fn main() -> mailpot::Result<()> { + #[doc = include_str!("./doctests/db_setup.rs.inc")] + /// assert_eq!( + /// &list.archive_header().unwrap(), + /// "" + /// ); + /// # Ok(()) + /// # } + /// ``` pub fn archive_header(&self) -> Option { self.archive_url.as_ref().map(|url| format!("<{}>", url)) }