use crate::grpc_protobuf::com::daml::ledger::api::v2::Identifier;
use std::fmt::{Display, Formatter, Result};
const PACKAGE_NAME_PREFIX: char = '#';
#[derive(Debug, PartialEq, Eq, Default, Clone, Hash, Ord, PartialOrd)]
pub struct DamlIdentifier {
package_ref: String,
module_name: String,
entity_name: String,
}
impl DamlIdentifier {
pub fn new(package_ref: impl Into<String>, module_name: impl Into<String>, entity_name: impl Into<String>) -> Self {
Self {
package_ref: package_ref.into(),
module_name: module_name.into(),
entity_name: entity_name.into(),
}
}
pub fn from_package_name(
package_name: impl AsRef<str>,
module_name: impl Into<String>,
entity_name: impl Into<String>,
) -> Self {
Self::new(format!("{PACKAGE_NAME_PREFIX}{}", package_name.as_ref()), module_name, entity_name)
}
pub fn package_ref(&self) -> &str {
&self.package_ref
}
pub fn package_id(&self) -> Option<&str> {
if self.is_package_name() {
None
} else {
Some(&self.package_ref)
}
}
pub fn package_name(&self) -> Option<&str> {
self.package_ref.strip_prefix(PACKAGE_NAME_PREFIX)
}
pub fn is_package_name(&self) -> bool {
self.package_ref.starts_with(PACKAGE_NAME_PREFIX)
}
pub fn module_name(&self) -> &str {
&self.module_name
}
pub fn entity_name(&self) -> &str {
&self.entity_name
}
}
impl Display for DamlIdentifier {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}:{}:{}", self.package_ref, self.module_name, self.entity_name)
}
}
impl From<DamlIdentifier> for Identifier {
fn from(id: DamlIdentifier) -> Self {
Self {
package_id: id.package_ref,
module_name: id.module_name,
entity_name: id.entity_name,
}
}
}
impl From<Identifier> for DamlIdentifier {
fn from(id: Identifier) -> Self {
Self::new(id.package_id, id.module_name, id.entity_name)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn package_id_reference_roundtrips() {
let id = DamlIdentifier::new("abc123", "Foo.Bar", "Baz");
assert_eq!(id.package_id(), Some("abc123"));
assert_eq!(id.package_name(), None);
assert!(!id.is_package_name());
}
#[test]
fn package_name_reference_roundtrips() {
let id = DamlIdentifier::from_package_name("my-pkg", "Foo.Bar", "Baz");
assert_eq!(id.package_ref(), "#my-pkg");
assert_eq!(id.package_name(), Some("my-pkg"));
assert_eq!(id.package_id(), None);
assert!(id.is_package_name());
}
#[test]
fn display_uses_wire_form() {
let by_id = DamlIdentifier::new("abc", "M", "E");
assert_eq!(by_id.to_string(), "abc:M:E");
let by_name = DamlIdentifier::from_package_name("pkg", "M", "E");
assert_eq!(by_name.to_string(), "#pkg:M:E");
}
#[test]
fn proto_conversion_is_lossless() {
let original = DamlIdentifier::from_package_name("pkg", "M", "E");
let proto: Identifier = original.clone().into();
assert_eq!(proto.package_id, "#pkg");
let round_tripped = DamlIdentifier::from(proto);
assert_eq!(round_tripped, original);
}
}