1- use crate :: re:: TRACKING_ISSUE ;
1+ use crate :: re:: { REPOSITORY , TRACKING_ISSUE } ;
22use std:: fmt:: Display ;
33
4+ #[ derive( PartialEq , Eq , PartialOrd , Ord , Clone , Debug ) ]
5+ pub struct Repository {
6+ /// Something like `rust-lang`
7+ pub org : String ,
8+
9+ /// Something like `rust-project-goals`
10+ pub repo : String ,
11+ }
12+
13+ impl Repository {
14+ pub fn new ( org : & ( impl Display + ?Sized ) , repo : & ( impl Display + ?Sized ) ) -> Self {
15+ Self {
16+ org : org. to_string ( ) ,
17+ repo : repo. to_string ( ) ,
18+ }
19+ }
20+ }
21+
22+ impl std:: fmt:: Display for Repository {
23+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
24+ let Repository { org, repo } = self ;
25+ write ! ( f, "{org}/{repo}" )
26+ }
27+ }
28+
29+ impl std:: str:: FromStr for Repository {
30+ type Err = anyhow:: Error ;
31+
32+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
33+ let Some ( c) = REPOSITORY . captures ( s) else {
34+ anyhow:: bail!( "invalid repository `{s}`" )
35+ } ;
36+
37+ Ok ( Repository :: new ( & c[ 1 ] , & c[ 2 ] ) )
38+ }
39+ }
40+
441#[ derive( PartialEq , Eq , PartialOrd , Ord , Clone ) ]
542pub struct IssueId {
6- /// Something like `rust-lang/rust-project-goals`
7- pub repository : String ,
43+ pub repository : Repository ,
844
945 /// Something like `22`
1046 pub number : u64 ,
1147}
1248
1349impl IssueId {
14- pub fn new ( repository : & ( impl Display + ?Sized ) , number : u64 ) -> Self {
15- Self {
16- repository : repository. to_string ( ) ,
50+ pub fn new ( repository : Repository , number : u64 ) -> Self {
51+ Self { repository, number }
52+ }
53+
54+ pub fn url ( & self ) -> String {
55+ let IssueId {
56+ repository : Repository { org, repo } ,
1757 number,
18- }
58+ } = self ;
59+ format ! ( "https://github.com/{org}/{repo}/issues/{number}" )
1960 }
2061}
2162
@@ -27,12 +68,11 @@ impl std::fmt::Debug for IssueId {
2768
2869impl std:: fmt:: Display for IssueId {
2970 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
30- write ! (
31- f,
32- "[{repository}#{number}]" ,
33- repository = self . repository,
34- number = self . number,
35- )
71+ let IssueId {
72+ repository : Repository { org, repo } ,
73+ number,
74+ } = self ;
75+ write ! ( f, "[{org}/{repo}#{number}]" )
3676 }
3777}
3878
@@ -44,6 +84,6 @@ impl std::str::FromStr for IssueId {
4484 anyhow:: bail!( "invalid issue-id" )
4585 } ;
4686
47- Ok ( IssueId :: new ( & c[ 1 ] , c[ 2 ] . parse ( ) ?) )
87+ Ok ( IssueId :: new ( Repository :: new ( & c[ 1 ] , & c[ 2 ] ) , c [ 3 ] . parse ( ) ?) )
4888 }
4989}
0 commit comments