rib/
type_parameter.rs

1// Copyright 2024-2025 Golem Cloud
2//
3// Licensed under the Golem Source License v1.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://license.golem.cloud/LICENSE
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::type_parameter_parser::type_parameter;
16use bincode::{Decode, Encode};
17use combine::stream::position;
18use combine::EasyParser;
19use std::fmt;
20use std::fmt::Display;
21
22// The type parameter which can be part of instance creation or worker function call
23#[derive(Debug, Hash, Clone, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)]
24pub enum TypeParameter {
25    Interface(InterfaceName),
26    PackageName(PackageName),
27    FullyQualifiedInterface(FullyQualifiedInterfaceName),
28}
29
30impl TypeParameter {
31    pub fn get_package_name(&self) -> Option<PackageName> {
32        match self {
33            TypeParameter::Interface(_) => None,
34            TypeParameter::PackageName(package) => Some(package.clone()),
35            TypeParameter::FullyQualifiedInterface(qualified) => {
36                Some(qualified.package_name.clone())
37            }
38        }
39    }
40
41    pub fn get_interface_name(&self) -> Option<InterfaceName> {
42        match self {
43            TypeParameter::Interface(interface) => Some(interface.clone()),
44            TypeParameter::PackageName(_) => None,
45            TypeParameter::FullyQualifiedInterface(qualified) => {
46                Some(qualified.interface_name.clone())
47            }
48        }
49    }
50
51    pub fn from_text(input: &str) -> Result<TypeParameter, String> {
52        type_parameter()
53            .easy_parse(position::Stream::new(input))
54            .map(|t| t.0)
55            .map_err(|err| format!("Invalid type parameter type {err}"))
56    }
57}
58
59impl Display for TypeParameter {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        match self {
62            TypeParameter::Interface(interface) => write!(f, "{interface}"),
63            TypeParameter::PackageName(package) => write!(f, "{package}"),
64            TypeParameter::FullyQualifiedInterface(qualified) => write!(f, "{qualified}"),
65        }
66    }
67}
68
69// foo@1.0.0
70#[derive(Debug, Hash, Clone, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)]
71pub struct InterfaceName {
72    pub name: String,
73    pub version: Option<String>,
74}
75
76impl Display for InterfaceName {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        write!(f, "{}", self.name)?;
79        if let Some(version) = &self.version {
80            write!(f, "@{version}")?;
81        }
82        Ok(())
83    }
84}
85
86// ns2:pkg2@1.0.0
87#[derive(Debug, Hash, Clone, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)]
88pub struct PackageName {
89    pub namespace: String,
90    pub package_name: String,
91    pub version: Option<String>,
92}
93
94impl Display for PackageName {
95    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96        write!(f, "{}:{}", self.namespace, self.package_name)?;
97        if let Some(version) = &self.version {
98            write!(f, "@{version}")?;
99        }
100        Ok(())
101    }
102}
103
104// ns2:pkg2/foo@1.0.0
105#[derive(Debug, Hash, Clone, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)]
106pub struct FullyQualifiedInterfaceName {
107    pub package_name: PackageName,
108    pub interface_name: InterfaceName,
109}
110
111impl Display for FullyQualifiedInterfaceName {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        write!(f, "{}/{}", self.package_name, self.interface_name)
114    }
115}