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