/// Provides an implementation of the [IndieAuth](https://indieauth.spec.indieweb.org) standard.
///
/// The implementations in this crate allows for one to
/// [request][indieauth::Request::BuildAuthorizationUrl] a [Token][indieauth::Token],
/// [verify][indieauth::Request::VerifyAccessToken] it and other common operations. All
/// known operations can be found under the [request][indieauth::Request] representation
/// as well as [the responses][indieauth::Response].
///
/// # Requesting A Token
/// In order to request a [token][indieauth::Token] or a [profile][indieauth::Profile], one needs
/// to construct an authorization URL that'll allow the user to provide you with an authorization
/// code. You can build the such by doing the following:
///
/// ```
/// use indieweb::standards::indieauth;
/// use indieweb::http::reqwest::Client as HttpClient;
/// use indieauth::Client;
/// use url::Url;
///
/// // Get networking client.
/// let http_client = HttpClient::default();
///
/// // Define who I want to be.
/// let me: Url = "https://jacky.wtf".parse().unwrap();
///
/// // Create a simple client for making requests.
/// let client: indieauth::Client = (
///     indieauth::ClientId::new("https://jacky.wtf".into()),
///     indieauth::EndpointDiscovery::Classic {
///         authorization: "https://jacky.wtf/auth/auth".parse().unwrap(),
///         token: "https://jacky.wtf/auth/token".parse().unwrap(),
///         ticket: None
///     }).into();
///
/// // Build the authorization URL to get an authorization code.
/// let response = client.dispatch(&http_client,
///     indieauth::Request::BuildAuthorizationUrl {
///         me: Some(me.clone()),
///         scope: None,
///         redirect_uri: None
///     });
///
/// // Prune out the fields from the request.
/// # tokio_test::block_on(async {
/// let response_opt: Option<(_, _, _, _)> = response.await.as_ref()
///         .ok()
///         .and_then(|r| {
///             if let indieauth::Response::AuthenticationUrl { url, verifier, challenge,
///             csrf_token, issuer: _ } = r {
///                 Some((url.clone(), challenge.clone(), verifier.clone(), csrf_token.clone()))
///                   .filter(|_| {
///                     url.query_pairs().any(|(key, value)| {
///                         key == "me" && value == me.as_str()
///                     })
///                   })
///             } else {
///                 None
///             }
///          })
///          .clone();
///
///  assert!(
///     response_opt
///         .as_ref()
///         .map(|(url, _, _, _)| url)
///         .map(|url| {
///             url.query_pairs().any(|(key, value)| {
///                 key == "me" && value == me.as_str()
///             })
///         }).unwrap_or(false),
///     "confirms the authorization URL to send the user to on behalf of them");
/// # })
/// // Direct the user to the location of `response_opt.unwrap().0`.
/// ```
///
/// # Redeeming an Authorization Code
/// The IndieAuth server will do the work of confirming the identity and scopes
/// that the site ends up permitting. You'll be redirected back to with an authoriz
/// ation code or error information. This step is meant to help capture that kind
/// of information.
///
/// ## Note
/// * The logic for checking CSRF tokens is up to your implementation. It's
///   strongly recommended to do to prevent forged requests.
///
/// ```
/// use indieweb::{
///     standards::indieauth::{
///         Client, EndpointDiscovery, ClientId, AuthUrl, TokenUrl, 
///         Request, DesiredResourceAuthorization, AuthorizationCode
///     },
///     http::reqwest::Client as HttpClient
/// };
///
/// let http_client = HttpClient::default();
///
/// let client: Client = (
///    ClientId::new("https://jacky.wtf".into()),
///    EndpointDiscovery::Classic {
///      authorization: "https://jacky.wtf/auth/auth".parse().unwrap(),
///      token: "https://jacky.wtf/auth/token".parse().unwrap(),
///      ticket: None
///    }
/// ).into();
///
/// let code = AuthorizationCode::new("abcdefghijklmnopqrstuvxwyz123456".to_string());
///
/// client.dispatch(&http_client, Request::CompleteAuthorization {
///   code,
///   resource: DesiredResourceAuthorization::Profile,
///   code_verifier: String::default(),
///   redirect_uri: None
/// });
/// ```
///
/// The expected response from that dispatch call could be either the providing of
/// a [profile][indieauth::Response::Profile] or of a [token][indieauth::Response::AccessToken].
// FIXME: Work on a mocked out client that'll provide fixture information for the IndieAuth flow.
///
/// # Verifying A Token
/// The act of verification is done by doing the following:
///
/// ```
/// use indieweb::{
///     standards::indieauth::{AccessToken, Client,
///         EndpointDiscovery, EndpointMetadata,
///         ClientId, AuthUrl, TokenUrl, Request, DesiredResourceAuthorization},
///     http::reqwest::Client as HttpClient
/// };
///
/// let http_client = HttpClient::default();
///
/// let client: Client = (
///    ClientId::new("https://jacky.wtf".into()),
///    EndpointDiscovery::Classic {
///     authorization: "https://jacky.wtf/auth/auth".parse().unwrap(),
///     token: "https://jacky.wtf/auth/token".parse().unwrap(),
///     ticket: None
///    }
/// ).into();
/// let token = AccessToken::new("magic-token".to_string());
///
/// client.dispatch(&http_client, Request::VerifyAccessToken(token));
/// ```
///
///
/// What's missing from this implementation is logic for things like
/// [AutoAuth](https://indieweb.org/AutoAuth) or
/// [TicketAuth](https://indieweb.org/IndieAuth_Ticket_Auth). This also
/// is locked at the
/// [26 Nov 2020 version](https://indieauth.spec.indieweb.org/#changes-from-26-november-2020-to-this-version=).
pub mod indieauth;

/// Provides an implementation of the [Micropub](https://micropub.spec.indieweb.org) standard.
///
/// This provides a means of representing a Micropub [query][crate::standards::micropub::Query]
/// and parsing the [responses][crate::standards::micropub::QueryResponse] produced by 
/// conforming servers or invoking an [action][micropub::Action] and handling that 
/// [response][crate::standards::micropub::ActionResponse] accordingly.
pub mod micropub;

/// Provides an implementation of the [Webmention](https://www.w3.org/TR/webmention/) standard.
///
/// This provides logic for [sending Webmentions][crate::standards::webmention::send],
/// [determining the kind of Webmention][crate::standards::webmention::mention_relationship] and
/// structures around things like [private Webmentions][crate::standards::webmention::PrivateRequest].
///
/// See [send][crate::standards::webmention::send] for more information.
pub mod webmention;
