1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! This crate brings Slack's terrific [Block Kit 🔗] to
//! the Rust ecosystem.
//!
//! This crate should hopefully come in handy if you need to
//! build some rich functionality, or just want to send some
//! slack messages without having to know Block Kit.
//!
//! Inside, you'll find simple models with an API that is
//! thoroughly documented and (hopefully) easy to use.
//!
//! This is currently being actively developed so watch the repo for a
//! stable v1 release!
//!
//! [Block Kit 🔗]: https://api.slack.com/block-kit
//!
//! # Build / Test / Format
//! This crate uses [`cargo-make`] for script consistency, in Makefile.toml you'll find:
//!   - `cargo make fmt`: Format all files according to configured style `rustfmt.toml`
//!   - `cargo make test`: Run all tests
//!   - `cargo make doctest`: Run doc tests only
//!   - `cargo make tdd`: Watch files for changes, and run `cargo make test` on each change
//!   - `cargo make ci`: Run tests, check that code is formatted and no lint violations.
//!                      This is run as a quality gate for all pull requests.
//!
//! # Contributing
//!
//! If you're interested in contributing, head over to the [issues] and see what's left to
//! do to get this crate fully usable and stable - at the time of writing there are a few
//! big-picture things left to do:
//!
//! - Implement Block Elements ([#61](https://github.com/cakekindel/slack-blocks-rs/issues/61))
//! - ~~Implement Composition Objects ([#63](https://github.com/cakekindel/slack-blocks-rs/issues/63))~~
//! - Remove the `validator` crate from the public API ([#9](https://github.com/cakekindel/slack-blocks-rs/issues/9))
//! - Add a `validation` crate feature ([#8](https://github.com/cakekindel/slack-blocks-rs/issues/8))
//!
//! And this doesn't block a v1.0.0, but is definitely something I'm interested in doing for this crate,
//! that will make it a lot nicer to interact with:
//! - Add a proc-macro of some kind that allows easy creation of block messages (#??)
//!
//! This repo follows [Conventional Commits] in order to fully automate the semver process,
//! but you don't _need_ to follow this convention since the repo is configured for Squash
//! commits on merge.
//!
//! [`cargo-make`]: https://github.com/sagiegurari/cargo-make/
//! [issues]: https://github.com/cakekindel/slack-blocks-rs/issues/
//! [Conventional Commits]: https://www.conventionalcommits.org/en/v1.0.0/

#![deny(missing_docs)]
#![cfg_attr(not(test),
            forbid(missing_copy_implementations,
                   missing_debug_implementations,
                   unreachable_pub,
                   unsafe_code,
                   unused_crate_dependencies))]
#![allow(deprecated)] // temporary

#[macro_use]
extern crate validator_derive;

#[doc(inline)]
pub mod blocks;
#[doc(inline)]
pub mod compose;
#[doc(inline)]
pub mod elems;

mod build;
mod val_helpr;

#[doc(inline)]
pub use blocks::Block;
#[doc(inline)]
pub use compose::text;
#[doc(inline)]
pub use elems::BlockElement;

mod macros {
  #[macro_export]
  #[doc(hidden)]
  macro_rules! convert {
    (impl From<$source:ty> for $dest:ty => $closure:expr) => {
      impl From<$source> for $dest {
        fn from(src: $source) -> Self {
          $closure(src)
        }
      }
    };
    (impl<'_> From<$source:ident> for $dest:ident => $closure:expr) => {
      impl<'a> From<$source<'a>> for $dest<'a> {
        fn from(src: $source<'a>) -> $dest<'a> {
          $closure(src)
        }
      }
    };
    (impl<$lifetime:lifetime> From<$source:ty> for $dest:ty => $closure:expr) => {
      convert!(impl<$lifetime, > From<$source> for $dest => $closure);
    };
    (impl<$lifetime:lifetime, $($ty_var:ident),*> From<$source:ty> for $dest:ty => $closure:expr) => {
      impl<$lifetime, $($ty_var),*> From<$source> for $dest {
        fn from(src: $source) -> Self {
          $closure(src)
        }
      }
    };
    (impl<$($ty_var:tt),+> From<$source:ty> for $dest:ty => $closure:expr) => {
      impl<$($ty_var),+> From<$source> for $dest {
        fn from(src: $source) -> Self {
          $closure(src)
        }
      }
    };
    (impl From<impl $trait_:ident<$source:ty>> for $dest:ty => $closure:expr) => {
      impl<T> From<T> for $dest where T: $trait_<$source>
      {
        fn from(src: T) -> Self {
          $closure(src)
        }
      }
    };
    (impl<'_> From<impl $trait_:ident<$source:ident>> for $dest:ident => |$param:ident| $body:expr) => {
      impl<'a, T> From<T> for $dest<'a> where T: $trait_<$source<'a>>
      {
        fn from($param: T) -> Self {
          $body
        }
      }
    };
  }
}