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}