refactor: make a proper new type for TagName

Make TagName into a new type (struct), instead of a type alias for
RefString. This provide stronger type safety, for the cost of a little
more implementation work. For the needs of the CI broker, that's two
methods and two trait impls.

Signed-off-by: Lars Wirzenius <liw@liw.fi>
This commit is contained in:
Lars Wirzenius
2025-04-07 16:02:03 +03:00
parent 0bda319b54
commit 904f4bb249
3 changed files with 37 additions and 6 deletions
+5 -2
View File
@@ -708,7 +708,7 @@ impl ParsedRef {
if let Some(captures) = re.captures(refname) {
if let Some(tag_name) = captures.get(1) {
if let Ok(tag_name) = ref_string(tag_name.as_str()) {
return Some(ParsedRef::Tag(tag_name));
return Some(ParsedRef::Tag(tag_name.into()));
}
}
}
@@ -758,6 +758,9 @@ mod test_parsed_ref {
fn tag() {
let actual = ref_string("refs/namespaces/NID/refs/tags/v0.0.0").unwrap();
let wanted = ref_string("v0.0.0").unwrap();
assert_eq!(ParsedRef::parse_ref(&actual), Some(ParsedRef::Tag(wanted)));
assert_eq!(
ParsedRef::parse_ref(&actual),
Some(ParsedRef::Tag(wanted.into()))
);
}
}
+3 -3
View File
@@ -260,16 +260,16 @@ impl PageData {
repo,
tag,
tip,
}) => render_event(repo, self.repo_alias(*repo), tag, tip),
}) => render_event(repo, self.repo_alias(*repo), tag.as_str(), tip),
CiEvent::V1(CiEventV1::TagUpdated {
from_node: _,
repo,
tag,
tip,
old_tip: _,
}) => render_event(repo, self.repo_alias(*repo), tag, tip),
}) => render_event(repo, self.repo_alias(*repo), tag.as_str(), tip),
CiEvent::V1(CiEventV1::TagDeleted { repo, tag, tip, .. }) => {
render_event(repo, self.repo_alias(*repo), tag, tip)
render_event(repo, self.repo_alias(*repo), tag.as_str(), tip)
}
CiEvent::V1(CiEventV1::PatchCreated {
from_node: _,
+29 -1
View File
@@ -2,13 +2,41 @@
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use radicle::{
cob::patch::PatchId,
git::{BranchName, Component, Namespaced, Qualified, RefStr, RefString},
};
/// A tag name.
pub type TagName = RefString;
///
/// This is exactly like a [`RefString`], but meant to have stronger
/// type safety as a separate type. It's also more self-documenting.
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct TagName(RefString);
impl TagName {
pub fn starts_with(&self, s: &str) -> bool {
self.as_ref().starts_with(s)
}
pub fn as_str(&self) -> &str {
self.as_ref()
}
}
impl From<RefString> for TagName {
fn from(from: RefString) -> Self {
Self(from)
}
}
impl AsRef<str> for TagName {
fn as_ref(&self) -> &str {
self.0.as_str()
}
}
/// Convert a plain branch name (`main`) from a Git ref
pub fn branch_ref(name: &RefStr) -> Result<BranchName, RefError> {