harmos_domain/operations/common/
grpc.rs1use std::borrow::Cow;
18
19use serde::{Deserialize, Serialize};
21
22#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
33#[serde(deny_unknown_fields)]
34pub struct Grpc {
35 pub package: Cow<'static, str>,
36 pub service: Cow<'static, str>,
37 pub method: Cow<'static, str>,
38}
39
40impl Grpc {
47 pub const fn new(package: &'static str, service: &'static str, method: &'static str) -> Self {
48 Self { package: Cow::Borrowed(package), service: Cow::Borrowed(service), method: Cow::Borrowed(method) }
49 }
50
51 pub fn validate(&self) -> Result<(), super::ContractError> {
52 if self.package.is_empty()
53 || self.package.len() > 255
54 || !self.package.split('.').all(identifier)
55 || !identifier(&self.service)
56 || !identifier(&self.method)
57 || self.package.starts_with("grpc.")
58 {
59 return Err(super::ContractError::Grpc);
60 }
61 Ok(())
62 }
63
64 pub fn path(&self) -> String {
65 format!("/{}.{}/{}", self.package, self.service, self.method)
66 }
67}
68
69fn identifier(value: &str) -> bool {
74 let mut bytes = value.bytes();
75 value.len() <= 255
76 && bytes.next().is_some_and(|byte| byte.is_ascii_alphabetic() || byte == b'_')
77 && bytes.all(|byte| byte.is_ascii_alphanumeric() || byte == b'_')
78}
79
80