ParseDiscussionOrCommentArg parses a positional argument that can be a discussion number, discussion URL, comment node ID (DC_...), or comment URL (with a "#discussioncomment-NNNNN" fragment).
(arg string)
| 65 | // ParseDiscussionOrCommentArg parses a positional argument that can be a discussion number, |
| 66 | // discussion URL, comment node ID (DC_...), or comment URL (with a "#discussioncomment-NNNNN" fragment). |
| 67 | func ParseDiscussionOrCommentArg(arg string) (*ParsedDiscussionOrCommentArg, error) { |
| 68 | if strings.HasPrefix(arg, "DC_") { |
| 69 | return &ParsedDiscussionOrCommentArg{CommentNodeID: arg}, nil |
| 70 | } |
| 71 | |
| 72 | if num, err := strconv.ParseInt(arg, 10, 32); err == nil { |
| 73 | return &ParsedDiscussionOrCommentArg{Number: int32(num)}, nil |
| 74 | } |
| 75 | if len(arg) > 1 && arg[0] == '#' { |
| 76 | if num, err := strconv.ParseInt(arg[1:], 10, 32); err == nil { |
| 77 | return &ParsedDiscussionOrCommentArg{Number: int32(num)}, nil |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | u, err := url.Parse(arg) |
| 82 | if err != nil || (u.Scheme != "http" && u.Scheme != "https") { |
| 83 | return nil, fmt.Errorf("invalid argument: %q (expected a discussion number, URL, or comment ID)", arg) |
| 84 | } |
| 85 | |
| 86 | m := discussionURLRE.FindStringSubmatch(u.Path) |
| 87 | if m == nil { |
| 88 | return nil, fmt.Errorf("invalid discussion URL: %q", arg) |
| 89 | } |
| 90 | |
| 91 | num, err := strconv.ParseInt(m[3], 10, 32) |
| 92 | if err != nil { |
| 93 | return nil, fmt.Errorf("invalid discussion number in URL: %q", m[3]) |
| 94 | } |
| 95 | repo := ghrepo.NewWithHost(m[1], m[2], u.Hostname()) |
| 96 | |
| 97 | if fragment := u.Fragment; strings.HasPrefix(fragment, "discussioncomment-") { |
| 98 | commentNumStr := strings.TrimPrefix(fragment, "discussioncomment-") |
| 99 | commentNum, err := strconv.ParseInt(commentNumStr, 10, 64) |
| 100 | if err != nil { |
| 101 | return nil, fmt.Errorf("invalid comment ID in URL fragment: %q", fragment) |
| 102 | } |
| 103 | return &ParsedDiscussionOrCommentArg{ |
| 104 | Number: int32(num), |
| 105 | Repo: repo, |
| 106 | CommentDatabaseID: commentNum, |
| 107 | }, nil |
| 108 | } |
| 109 | |
| 110 | return &ParsedDiscussionOrCommentArg{Number: int32(num), Repo: repo}, nil |
| 111 | } |