typed-openrpc 0.1.1

Typed JSON-RPC 2.0 method definitions with OpenRPC document generation.
Documentation
use schemars::{JsonSchema, Schema};
use serde::{de::DeserializeOwned, Serialize};

/// Represents a JSON-RPC method with typed params and result.
pub trait RpcMethod {
    /// JSON-RPC method name.
    const NAME: &'static str;
    /// Short summary for documentation.
    const SUMMARY: &'static str;
    /// Optional tags describing the method.
    const TAGS: &'static [&'static str] = &[];
    /// Optional deprecation message.
    const DEPRECATED: Option<&'static str> = None;

    /// JSON-serializable params type.
    type Params: Serialize + DeserializeOwned + JsonSchema;
    /// JSON-serializable result type.
    type Result: Serialize + DeserializeOwned + JsonSchema;

    /// Generate JSON Schema for parameters.
    fn param_schema() -> Schema {
        schemars::schema_for!(Self::Params)
    }

    /// Generate JSON Schema for result.
    fn result_schema() -> Schema {
        schemars::schema_for!(Self::Result)
    }
}

/// Captures documentation for a JSON-RPC method.
#[derive(Clone, Debug)]
pub struct MethodDoc {
    pub name: String,
    pub summary: String,
    pub tags: Vec<String>,
    pub deprecation: Option<String>,
    pub params_schema: Schema,
    pub result_schema: Schema,
}

impl MethodDoc {
    /// Build documentation from a `RpcMethod` implementation.
    pub fn from<M: RpcMethod>() -> Self {
        Self {
            name: M::NAME.to_string(),
            summary: M::SUMMARY.to_string(),
            tags: M::TAGS.iter().map(|tag| tag.to_string()).collect(),
            deprecation: M::DEPRECATED.map(|msg| msg.to_string()),
            params_schema: M::param_schema(),
            result_schema: M::result_schema(),
        }
    }
}