diff --git a/Cargo.lock b/Cargo.lock index ff1a444..85e266b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "aho-corasick" -version = "0.7.10" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] @@ -45,6 +47,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "if_chain" version = "1.0.0" @@ -71,9 +83,9 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "memchr" -version = "2.3.3" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +checksum = "f478948fd84d9f8e86967bf432640e46adfb5a4bd4f14ef7e864ab38220534ae" [[package]] name = "mox" @@ -114,6 +126,30 @@ dependencies = [ "output_vt100", ] +[[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-macro2" version = "1.0.18" @@ -134,21 +170,32 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.9" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.18" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "ryu" @@ -223,34 +270,31 @@ dependencies = [ ] [[package]] -name = "thread_local" -version = "1.0.1" +name = "tinyvec" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ - "lazy_static", + "tinyvec_macros", ] [[package]] -name = "tinyvec" -version = "0.3.3" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "unicode-bidi" -version = "0.3.4" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -dependencies = [ - "matches", -] +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-normalization" -version = "0.1.13" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] @@ -267,18 +311,18 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" dependencies = [ - "idna", + "idna 0.2.0", "matches", "percent-encoding", ] [[package]] name = "validator" -version = "0.10.1" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e60fadf92c22236de4028ceb0b8af50ed3430d41ad43d7a7d63b6bd1a8f47c38" +checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd" dependencies = [ - "idna", + "idna 0.4.0", "lazy_static", "regex", "serde", @@ -289,19 +333,36 @@ dependencies = [ [[package]] name = "validator_derive" -version = "0.10.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d577dfb8ca9440a5c0b053d5a19b68f5c92ef57064bac87c8205c3f6072c20f" +checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af" dependencies = [ "if_chain", "lazy_static", + "proc-macro-error", "proc-macro2", "quote", "regex", "syn", - "validator", + "validator_types", +] + +[[package]] +name = "validator_types" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3" +dependencies = [ + "proc-macro2", + "syn", ] +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index d479ada..dedd93a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,8 +28,8 @@ maintenance = { status = "actively-developed" } [dependencies] serde = { version = "^1", features = ["derive"] } -validator = { version = "0.10.0", optional = true } -validator_derive = { version = "0.10.0", optional = true } +validator = { version = "0.16.0", optional = true } +validator_derive = { version = "0.16.0", optional = true } mox = { version = "0.12", optional = true } [dev-dependencies] diff --git a/src/blocks/header.rs b/src/blocks/header.rs index 938ee24..c0b1b95 100644 --- a/src/blocks/header.rs +++ b/src/blocks/header.rs @@ -11,8 +11,7 @@ use std::borrow::Cow; use serde::{Deserialize, Serialize}; -#[cfg(feature = "validation")] -use validator::Validate; + use crate::text; #[cfg(feature = "validation")] diff --git a/src/blocks/mod.rs b/src/blocks/mod.rs index 386631a..bffa6fc 100644 --- a/src/blocks/mod.rs +++ b/src/blocks/mod.rs @@ -43,6 +43,10 @@ pub mod header; #[doc(inline)] pub use header::Header; +pub mod rich_text; +#[doc(inline)] +pub use rich_text::RichText; + /// # Layout Blocks /// /// Blocks are a series of components that can be combined @@ -88,6 +92,9 @@ pub enum Block<'a> { /// # File Block File(File<'a>), + + /// # Rich Text Block + RichText(RichText<'a>), } impl fmt::Display for Block<'_> { @@ -101,6 +108,7 @@ impl fmt::Display for Block<'_> { | Block::Context { .. } => "Context", | Block::Input { .. } => "Input", | Block::File { .. } => "File", + | Block::RichText { .. } => "RichText", }; write!(f, "{}", kind) @@ -132,18 +140,20 @@ impl<'a> Block<'a> { | Input(contents) => contents.validate(), | Header(contents) => contents.validate(), | File(contents) => contents.validate(), + | RichText(contents) => validator::Validate::validate(contents), | Divider => Ok(()), } } } -convert!(impl<'a> From> for Block<'a> => |a| Block::Actions(a)); -convert!(impl<'a> From> for Block<'a> => |a| Block::Input(a)); -convert!(impl<'a> From> for Block<'a> => |a| Block::Section(a)); -convert!(impl<'a> From> for Block<'a> => |a| Block::Image(a)); -convert!(impl<'a> From> for Block<'a> => |a| Block::Context(a)); -convert!(impl<'a> From> for Block<'a> => |a| Block::File(a)); -convert!(impl<'a> From> for Block<'a> => |a| Block::Header(a)); +convert!(impl<'a> From> for Block<'a> => Block::RichText); +convert!(impl<'a> From> for Block<'a> => Block::Actions); +convert!(impl<'a> From> for Block<'a> => Block::Input); +convert!(impl<'a> From> for Block<'a> => Block::Section); +convert!(impl<'a> From> for Block<'a> => Block::Image); +convert!(impl<'a> From> for Block<'a> => Block::Context); +convert!(impl<'a> From> for Block<'a> => Block::File); +convert!(impl<'a> From> for Block<'a> => Block::Header); /// Error yielded when `TryFrom` is called on an unsupported block element. #[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)] diff --git a/src/blocks/rich_text.rs b/src/blocks/rich_text.rs new file mode 100644 index 0000000..547cd4c --- /dev/null +++ b/src/blocks/rich_text.rs @@ -0,0 +1,24 @@ +//! Undocumented rich text blocks + +#![allow(missing_docs)] + +use std::borrow::Cow; + +use crate::text; + +#[derive(Clone, Debug, serde::Deserialize, Hash, PartialEq, serde::Serialize)] +#[cfg_attr(feature = "validation", derive(Validate))] +pub struct RichText<'a> { + #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "validation", + validate(custom = "super::validate_block_id"))] + pub block_id: Option>, + pub elements: Vec, +} + +#[derive(Clone, Debug, serde::Deserialize, Hash, PartialEq, serde::Serialize)] +pub struct RichTextSection { + #[serde(rename = "type")] + pub ty: String, + pub elements: Vec, +} diff --git a/src/elems/image.rs b/src/elems/image.rs index ff5a890..562766b 100644 --- a/src/elems/image.rs +++ b/src/elems/image.rs @@ -15,8 +15,7 @@ use std::borrow::Cow; use serde::{Deserialize as De, Serialize as Ser}; -#[cfg(feature = "validation")] -use validator::Validate; + #[cfg(feature = "validation")] use crate::val_helpr::ValidationResult; diff --git a/tests/json/blocks/rich_text.rs b/tests/json/blocks/rich_text.rs new file mode 100644 index 0000000..8e58f1b --- /dev/null +++ b/tests/json/blocks/rich_text.rs @@ -0,0 +1,32 @@ +use pretty_assertions::assert_eq; +use serde_json::json; +use slack_blocks::{blocks::{self, RichText, rich_text::RichTextSection}, blox::*, text::ToSlackPlaintext}; + +/// +#[test] +pub fn issue_170() { + let button = blox! {}; + let block: blocks::Block = slack_blocks::Block::RichText(RichText { + block_id: Some("ommitted".into()), + elements: vec![RichTextSection { ty: "rich_text_section".into(), elements: vec!["foobar".plaintext()] }], +}); + + let actual = serde_json::to_value(block).expect("should serialize"); + let expected = json!({ + "type": "rich_text", + "block_id": "", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "foobar" + } + ] + } + ] + }); + + assert_eq!(actual, expected); +} diff --git a/tests/json/compose/option.rs b/tests/json/compose/option.rs index fa1c5d4..0df143c 100644 --- a/tests/json/compose/option.rs +++ b/tests/json/compose/option.rs @@ -1,6 +1,6 @@ use pretty_assertions::assert_eq; use serde_json::json; -use slack_blocks::{blocks, blox::*, text::ToSlackMarkdown}; +use slack_blocks::{blox::*}; #[test] pub fn option_docs_ex_1() {