harmos_domain/operations/
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 {
49 package: Cow::Borrowed(package),
50 service: Cow::Borrowed(service),
51 method: Cow::Borrowed(method),
52 }
53 }
54
55 pub fn validate(&self) -> Result<(), super::ContractError> {
56 if self.package.is_empty()
57 || self.package.len() > 255
58 || !self.package.split('.').all(identifier)
59 || !identifier(&self.service)
60 || !identifier(&self.method)
61 || self.package.starts_with("grpc.")
62 {
63 return Err(super::ContractError::Grpc);
64 }
65 Ok(())
66 }
67
68 pub fn path(&self) -> String {
69 format!("/{}.{}/{}", self.package, self.service, self.method)
70 }
71}
72
73fn identifier(value: &str) -> bool {
78 let mut bytes = value.bytes();
79 value.len() <= 255
80 && bytes.next().is_some_and(|byte| byte.is_ascii_alphabetic() || byte == b'_')
81 && bytes.all(|byte| byte.is_ascii_alphanumeric() || byte == b'_')
82}
83
84