dfhack_proto/
lib.rs

1#![warn(missing_docs)]
2#![doc = include_str!("../README.md")]
3
4use std::{fmt::Display, ops::Deref};
5
6/// Raw protobuf messages
7pub mod messages {
8    pub use crate::generated::messages::*;
9}
10
11/// Stubs exposing the feature of the DFHack remote API.
12///
13/// Each stub is generated from a DFHack plugin.
14/// This module is auto-generated from DFHack sources.
15pub mod stubs {
16    pub use crate::generated::stubs::*;
17}
18
19/// The `Channel` is the low-level exchange implementation.
20///
21/// It is in charge to serialize/deserialize messages, and exchange
22/// them with Dwarf Fortress. It is not meant to be used as is, but to be passed to
23/// It is analoguous to the gRPC channel.
24pub trait Channel {
25    /// Type of the errors raised by the stub.
26    ///
27    /// Defined by the channel implementation.
28    type TError;
29
30    /// Send a request to DFHack, and return its reply.
31    ///
32    /// # Errors
33    ///
34    /// The error type is defined by the channel implementation
35    ///
36    /// # Arguments
37    ///
38    /// * `plugin` - Name of the plugin implementing the request. Example: "RemoteFortressReader". Empty for core messages.
39    /// * `name` - Name of the method. Example: "GetDFVersion"
40    /// * `request` - Input of the method.
41    ///
42    /// # Returns
43    ///
44    /// A protobuf result type.
45    ///
46    fn request<TRequest: protobuf::MessageFull, TReply: protobuf::MessageFull>(
47        &mut self,
48        plugin: String,
49        name: String,
50        request: TRequest,
51    ) -> Result<Reply<TReply>, Self::TError>;
52}
53
54/// Reply to a request, it contains the actual reply value, and additional
55/// text fragments.
56pub struct Reply<T> {
57    /// The actual reply value
58    pub reply: T,
59    /// Additional text fragments received during the rpc
60    pub fragments: Vec<messages::CoreTextFragment>,
61}
62
63impl<T> Deref for Reply<T> {
64    type Target = T;
65
66    fn deref(&self) -> &Self::Target {
67        &self.reply
68    }
69}
70
71impl<T: Display> Display for Reply<T> {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        write!(f, "{}", self.reply)
74    }
75}
76
77#[cfg(feature = "reflection")]
78/// Reflection for runtime inspection of the stubs.
79pub mod reflection {
80    /// Descriptor of a remote procedure call
81    ///
82    /// These are all the needed information to make a call
83    pub struct RemoteProcedureDescriptor {
84        /// Name of the RPC
85        pub name: String,
86
87        /// Plugin implementing the RPC
88        ///
89        /// An empty string means the core API
90        pub plugin_name: String,
91
92        /// Input type
93        ///
94        /// This is the full name of the protobuf message
95        pub input_type: String,
96
97        /// Output type
98        ///
99        /// This is the full name of the protobuf message
100        pub output_type: String,
101    }
102
103    /// Ability for a stub to list its supported methods
104    ///
105    /// This is mostly useful for testing purpose.
106    pub trait StubReflection {
107        /// List the supported remote calls
108        fn list_methods() -> Vec<RemoteProcedureDescriptor>;
109    }
110}
111
112/// Generated code from this crate
113#[allow(clippy::let_unit_value)]
114mod generated {
115    pub mod messages;
116    pub mod stubs;
117}