gosuto_livekit/room/participant/
rpc.rs1use crate::room::participant::ParticipantIdentity;
16use livekit_protocol::RpcError as RpcError_Proto;
17use std::{error::Error, fmt::Display, time::Duration};
18
19#[derive(Debug, Clone)]
21pub struct PerformRpcData {
22 pub destination_identity: String,
23 pub method: String,
24 pub payload: String,
25 pub response_timeout: Duration,
26}
27
28impl Default for PerformRpcData {
29 fn default() -> Self {
30 Self {
31 destination_identity: Default::default(),
32 method: Default::default(),
33 payload: Default::default(),
34 response_timeout: Duration::from_secs(15),
35 }
36 }
37}
38
39#[derive(Debug, Clone)]
47pub struct RpcInvocationData {
48 pub request_id: String,
49 pub caller_identity: ParticipantIdentity,
50 pub payload: String,
51 pub response_timeout: Duration,
52}
53
54#[derive(Debug, Clone)]
61pub struct RpcError {
62 pub code: u32,
63 pub message: String,
64 pub data: Option<String>,
65}
66
67impl RpcError {
68 pub const MAX_MESSAGE_BYTES: usize = 256;
69 pub const MAX_DATA_BYTES: usize = 15360; pub fn new(code: u32, message: String, data: Option<String>) -> Self {
77 Self {
78 code,
79 message: truncate_bytes(&message, Self::MAX_MESSAGE_BYTES),
80 data: data.map(|d| truncate_bytes(&d, Self::MAX_DATA_BYTES)),
81 }
82 }
83
84 pub fn from_proto(proto: RpcError_Proto) -> Self {
85 Self::new(proto.code, proto.message, Some(proto.data))
86 }
87
88 pub fn to_proto(&self) -> RpcError_Proto {
89 RpcError_Proto {
90 code: self.code,
91 message: self.message.clone(),
92 data: self.data.clone().unwrap_or_default(),
93 }
94 }
95}
96
97impl Display for RpcError {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(f, "RPC Error: {} ({})", self.message, self.code)
100 }
101}
102impl Error for RpcError {}
103
104#[derive(Debug, Clone, Copy)]
105pub enum RpcErrorCode {
106 ApplicationError = 1500,
107 ConnectionTimeout = 1501,
108 ResponseTimeout = 1502,
109 RecipientDisconnected = 1503,
110 ResponsePayloadTooLarge = 1504,
111 SendFailed = 1505,
112
113 UnsupportedMethod = 1400,
114 RecipientNotFound = 1401,
115 RequestPayloadTooLarge = 1402,
116 UnsupportedServer = 1403,
117 UnsupportedVersion = 1404,
118}
119
120impl RpcErrorCode {
121 pub(crate) fn message(&self) -> &'static str {
122 match self {
123 Self::ApplicationError => "Application error in method handler",
124 Self::ConnectionTimeout => "Connection timeout",
125 Self::ResponseTimeout => "Response timeout",
126 Self::RecipientDisconnected => "Recipient disconnected",
127 Self::ResponsePayloadTooLarge => "Response payload too large",
128 Self::SendFailed => "Failed to send",
129
130 Self::UnsupportedMethod => "Method not supported at destination",
131 Self::RecipientNotFound => "Recipient not found",
132 Self::RequestPayloadTooLarge => "Request payload too large",
133 Self::UnsupportedServer => "RPC not supported by server",
134 Self::UnsupportedVersion => "Unsupported RPC version",
135 }
136 }
137}
138
139impl RpcError {
140 pub(crate) fn built_in(code: RpcErrorCode, data: Option<String>) -> Self {
142 Self::new(code as u32, code.message().to_string(), data)
143 }
144}
145
146pub const MAX_PAYLOAD_BYTES: usize = 15360; pub(crate) fn byte_length(s: &str) -> usize {
151 s.as_bytes().len()
152}
153
154pub(crate) fn truncate_bytes(s: &str, max_bytes: usize) -> String {
156 if byte_length(s) <= max_bytes {
157 return s.to_string();
158 }
159
160 let mut result = String::new();
161 for c in s.chars() {
162 if byte_length(&(result.clone() + &c.to_string())) > max_bytes {
163 break;
164 }
165 result.push(c);
166 }
167 result
168}