refactor: rename MessageType to IRCMessageType with full API
All checks were successful
check / check (push) Successful in 4s

- Rename MessageType to IRCMessageType (custom int type)
- .Name() returns just the name (e.g. "RPL_LUSEROP")
- .String() returns name + code (e.g. "RPL_LUSEROP <252>")
- .Code() returns zero-padded 3-digit string (e.g. "252")
- .Int() returns the bare int value
- Add FromInt() package-level function with validation
- Update all call sites to use new type and methods
This commit is contained in:
user
2026-03-10 10:31:22 -07:00
parent 164fec3fc8
commit ba2c113a85
3 changed files with 198 additions and 162 deletions

View File

@@ -746,8 +746,8 @@ func scanMessages(
code, _ := strconv.Atoi(msg.Command) code, _ := strconv.Atoi(msg.Command)
msg.Code = code msg.Code = code
if name := irc.Name(irc.MessageType(code)); name != "" { if mt, err := irc.FromInt(code); err == nil {
msg.Command = name msg.Command = mt.Name()
} }
} }

View File

@@ -398,12 +398,12 @@ func (hdlr *Handlers) serverName() string {
func (hdlr *Handlers) enqueueNumeric( func (hdlr *Handlers) enqueueNumeric(
ctx context.Context, ctx context.Context,
clientID int64, clientID int64,
code irc.MessageType, code irc.IRCMessageType,
nick string, nick string,
params []string, params []string,
text string, text string,
) { ) {
command := code.String() command := code.Code()
body, err := json.Marshal([]string{text}) body, err := json.Marshal([]string{text})
if err != nil { if err != nil {
@@ -969,7 +969,7 @@ func (hdlr *Handlers) respondIRCError(
writer http.ResponseWriter, writer http.ResponseWriter,
request *http.Request, request *http.Request,
clientID, sessionID int64, clientID, sessionID int64,
code irc.MessageType, code irc.IRCMessageType,
nick string, nick string,
params []string, params []string,
text string, text string,

View File

@@ -3,194 +3,228 @@
// RFC 1459 and RFC 2812, and standard command names. // RFC 1459 and RFC 2812, and standard command names.
package irc package irc
import "fmt" import (
"errors"
"fmt"
)
// MessageType represents an IRC numeric reply or error code. // IRCMessageType represents an IRC numeric reply or error code.
type MessageType int type IRCMessageType int //nolint:revive // Name requested by project owner.
// Name returns the standard IRC name for this numeric code // Name returns the standard IRC name for this numeric code
// (e.g., MessageType(2).Name() returns "RPL_YOURHOST"). // (e.g., IRCMessageType(252).Name() returns "RPL_LUSEROP").
// Returns an empty string if the code is unknown. // Returns an empty string if the code is unknown.
func (t MessageType) Name() string { func (t IRCMessageType) Name() string {
return names[t] return names[t]
} }
// String returns the three-digit zero-padded string representation // String returns the name and numeric code in angle brackets
// of the numeric code (e.g., MessageType(1).String() returns "001"). // (e.g., IRCMessageType(252).String() returns "RPL_LUSEROP <252>").
func (t MessageType) String() string { // If the code is unknown, returns "UNKNOWN <NNN>".
func (t IRCMessageType) String() string {
n := names[t]
if n == "" {
n = "UNKNOWN"
}
return fmt.Sprintf("%s <%03d>", n, int(t))
}
// Code returns the three-digit zero-padded string representation
// of the numeric code (e.g., IRCMessageType(252).Code() returns "252").
func (t IRCMessageType) Code() string {
return fmt.Sprintf("%03d", int(t)) return fmt.Sprintf("%03d", int(t))
} }
// Int returns the bare integer value of the numeric code.
func (t IRCMessageType) Int() int {
return int(t)
}
// ErrUnknownNumeric is returned by FromInt when the numeric code is not recognized.
var ErrUnknownNumeric = errors.New("unknown IRC numeric code")
// FromInt converts an integer to an IRCMessageType, returning an error
// if the numeric code is not a known IRC reply or error code.
func FromInt(n int) (IRCMessageType, error) {
t := IRCMessageType(n)
if _, ok := names[t]; !ok {
return 0, fmt.Errorf("%w: %d", ErrUnknownNumeric, n)
}
return t, nil
}
// Connection registration replies (001-005). // Connection registration replies (001-005).
const ( const (
RplWelcome MessageType = 1 RplWelcome IRCMessageType = 1
RplYourHost MessageType = 2 RplYourHost IRCMessageType = 2
RplCreated MessageType = 3 RplCreated IRCMessageType = 3
RplMyInfo MessageType = 4 RplMyInfo IRCMessageType = 4
RplBounce MessageType = 5 // RFC 2812; also known as RPL_ISUPPORT in practice RplBounce IRCMessageType = 5 // RFC 2812; also known as RPL_ISUPPORT in practice
RplIsupport MessageType = 5 // De-facto standard (same numeric as RplBounce) RplIsupport IRCMessageType = 5 // De-facto standard (same numeric as RplBounce)
) )
// Command responses (200-399). // Command responses (200-399).
const ( const (
// RFC 2812 trace/stats/links replies (200-219). // RFC 2812 trace/stats/links replies (200-219).
RplTraceLink MessageType = 200 RplTraceLink IRCMessageType = 200
RplTraceConnecting MessageType = 201 RplTraceConnecting IRCMessageType = 201
RplTraceHandshake MessageType = 202 RplTraceHandshake IRCMessageType = 202
RplTraceUnknown MessageType = 203 RplTraceUnknown IRCMessageType = 203
RplTraceOperator MessageType = 204 RplTraceOperator IRCMessageType = 204
RplTraceUser MessageType = 205 RplTraceUser IRCMessageType = 205
RplTraceServer MessageType = 206 RplTraceServer IRCMessageType = 206
RplTraceService MessageType = 207 RplTraceService IRCMessageType = 207
RplTraceNewType MessageType = 208 RplTraceNewType IRCMessageType = 208
RplTraceClass MessageType = 209 RplTraceClass IRCMessageType = 209
RplStatsLinkInfo MessageType = 211 RplStatsLinkInfo IRCMessageType = 211
RplStatsCommands MessageType = 212 RplStatsCommands IRCMessageType = 212
RplStatsCLine MessageType = 213 RplStatsCLine IRCMessageType = 213
RplStatsNLine MessageType = 214 RplStatsNLine IRCMessageType = 214
RplStatsILine MessageType = 215 RplStatsILine IRCMessageType = 215
RplStatsKLine MessageType = 216 RplStatsKLine IRCMessageType = 216
RplStatsQLine MessageType = 217 RplStatsQLine IRCMessageType = 217
RplStatsYLine MessageType = 218 RplStatsYLine IRCMessageType = 218
RplEndOfStats MessageType = 219 RplEndOfStats IRCMessageType = 219
RplUmodeIs MessageType = 221 RplUmodeIs IRCMessageType = 221
RplServList MessageType = 234 RplServList IRCMessageType = 234
RplServListEnd MessageType = 235 RplServListEnd IRCMessageType = 235
RplStatsLLine MessageType = 241 RplStatsLLine IRCMessageType = 241
RplStatsUptime MessageType = 242 RplStatsUptime IRCMessageType = 242
RplStatsOLine MessageType = 243 RplStatsOLine IRCMessageType = 243
RplStatsHLine MessageType = 244 RplStatsHLine IRCMessageType = 244
RplLuserClient MessageType = 251 RplLuserClient IRCMessageType = 251
RplLuserOp MessageType = 252 RplLuserOp IRCMessageType = 252
RplLuserUnknown MessageType = 253 RplLuserUnknown IRCMessageType = 253
RplLuserChannels MessageType = 254 RplLuserChannels IRCMessageType = 254
RplLuserMe MessageType = 255 RplLuserMe IRCMessageType = 255
RplAdminMe MessageType = 256 RplAdminMe IRCMessageType = 256
RplAdminLoc1 MessageType = 257 RplAdminLoc1 IRCMessageType = 257
RplAdminLoc2 MessageType = 258 RplAdminLoc2 IRCMessageType = 258
RplAdminEmail MessageType = 259 RplAdminEmail IRCMessageType = 259
RplTraceLog MessageType = 261 RplTraceLog IRCMessageType = 261
RplTraceEnd MessageType = 262 RplTraceEnd IRCMessageType = 262
RplTryAgain MessageType = 263 RplTryAgain IRCMessageType = 263
RplAway MessageType = 301 RplAway IRCMessageType = 301
RplUserHost MessageType = 302 RplUserHost IRCMessageType = 302
RplIson MessageType = 303 RplIson IRCMessageType = 303
RplUnaway MessageType = 305 RplUnaway IRCMessageType = 305
RplNowAway MessageType = 306 RplNowAway IRCMessageType = 306
RplWhoisUser MessageType = 311 RplWhoisUser IRCMessageType = 311
RplWhoisServer MessageType = 312 RplWhoisServer IRCMessageType = 312
RplWhoisOperator MessageType = 313 RplWhoisOperator IRCMessageType = 313
RplWhoWasUser MessageType = 314 RplWhoWasUser IRCMessageType = 314
RplEndOfWho MessageType = 315 RplEndOfWho IRCMessageType = 315
RplWhoisIdle MessageType = 317 RplWhoisIdle IRCMessageType = 317
RplEndOfWhois MessageType = 318 RplEndOfWhois IRCMessageType = 318
RplWhoisChannels MessageType = 319 RplWhoisChannels IRCMessageType = 319
RplListStart MessageType = 321 RplListStart IRCMessageType = 321
RplList MessageType = 322 RplList IRCMessageType = 322
RplListEnd MessageType = 323 RplListEnd IRCMessageType = 323
RplChannelModeIs MessageType = 324 RplChannelModeIs IRCMessageType = 324
RplUniqOpIs MessageType = 325 RplUniqOpIs IRCMessageType = 325
RplCreationTime MessageType = 329 RplCreationTime IRCMessageType = 329
RplNoTopic MessageType = 331 RplNoTopic IRCMessageType = 331
RplTopic MessageType = 332 RplTopic IRCMessageType = 332
RplTopicWhoTime MessageType = 333 RplTopicWhoTime IRCMessageType = 333
RplInviting MessageType = 341 RplInviting IRCMessageType = 341
RplSummoning MessageType = 342 RplSummoning IRCMessageType = 342
RplInviteList MessageType = 346 RplInviteList IRCMessageType = 346
RplEndOfInviteList MessageType = 347 RplEndOfInviteList IRCMessageType = 347
RplExceptList MessageType = 348 RplExceptList IRCMessageType = 348
RplEndOfExceptList MessageType = 349 RplEndOfExceptList IRCMessageType = 349
RplVersion MessageType = 351 RplVersion IRCMessageType = 351
RplWhoReply MessageType = 352 RplWhoReply IRCMessageType = 352
RplNamReply MessageType = 353 RplNamReply IRCMessageType = 353
RplLinks MessageType = 364 RplLinks IRCMessageType = 364
RplEndOfLinks MessageType = 365 RplEndOfLinks IRCMessageType = 365
RplEndOfNames MessageType = 366 RplEndOfNames IRCMessageType = 366
RplBanList MessageType = 367 RplBanList IRCMessageType = 367
RplEndOfBanList MessageType = 368 RplEndOfBanList IRCMessageType = 368
RplEndOfWhowas MessageType = 369 RplEndOfWhowas IRCMessageType = 369
RplInfo MessageType = 371 RplInfo IRCMessageType = 371
RplMotd MessageType = 372 RplMotd IRCMessageType = 372
RplEndOfInfo MessageType = 374 RplEndOfInfo IRCMessageType = 374
RplMotdStart MessageType = 375 RplMotdStart IRCMessageType = 375
RplEndOfMotd MessageType = 376 RplEndOfMotd IRCMessageType = 376
RplYoureOper MessageType = 381 RplYoureOper IRCMessageType = 381
RplRehashing MessageType = 382 RplRehashing IRCMessageType = 382
RplYoureService MessageType = 383 RplYoureService IRCMessageType = 383
RplTime MessageType = 391 RplTime IRCMessageType = 391
RplUsersStart MessageType = 392 RplUsersStart IRCMessageType = 392
RplUsers MessageType = 393 RplUsers IRCMessageType = 393
RplEndOfUsers MessageType = 394 RplEndOfUsers IRCMessageType = 394
RplNoUsers MessageType = 395 RplNoUsers IRCMessageType = 395
) )
// Error replies (400-599). // Error replies (400-599).
const ( const (
ErrNoSuchNick MessageType = 401 ErrNoSuchNick IRCMessageType = 401
ErrNoSuchServer MessageType = 402 ErrNoSuchServer IRCMessageType = 402
ErrNoSuchChannel MessageType = 403 ErrNoSuchChannel IRCMessageType = 403
ErrCannotSendToChan MessageType = 404 ErrCannotSendToChan IRCMessageType = 404
ErrTooManyChannels MessageType = 405 ErrTooManyChannels IRCMessageType = 405
ErrWasNoSuchNick MessageType = 406 ErrWasNoSuchNick IRCMessageType = 406
ErrTooManyTargets MessageType = 407 ErrTooManyTargets IRCMessageType = 407
ErrNoSuchService MessageType = 408 ErrNoSuchService IRCMessageType = 408
ErrNoOrigin MessageType = 409 ErrNoOrigin IRCMessageType = 409
ErrNoRecipient MessageType = 411 ErrNoRecipient IRCMessageType = 411
ErrNoTextToSend MessageType = 412 ErrNoTextToSend IRCMessageType = 412
ErrNoTopLevel MessageType = 413 ErrNoTopLevel IRCMessageType = 413
ErrWildTopLevel MessageType = 414 ErrWildTopLevel IRCMessageType = 414
ErrBadMask MessageType = 415 ErrBadMask IRCMessageType = 415
ErrUnknownCommand MessageType = 421 ErrUnknownCommand IRCMessageType = 421
ErrNoMotd MessageType = 422 ErrNoMotd IRCMessageType = 422
ErrNoAdminInfo MessageType = 423 ErrNoAdminInfo IRCMessageType = 423
ErrFileError MessageType = 424 ErrFileError IRCMessageType = 424
ErrNoNicknameGiven MessageType = 431 ErrNoNicknameGiven IRCMessageType = 431
ErrErroneusNickname MessageType = 432 ErrErroneusNickname IRCMessageType = 432
ErrNicknameInUse MessageType = 433 ErrNicknameInUse IRCMessageType = 433
ErrNickCollision MessageType = 436 ErrNickCollision IRCMessageType = 436
ErrUnavailResource MessageType = 437 ErrUnavailResource IRCMessageType = 437
ErrUserNotInChannel MessageType = 441 ErrUserNotInChannel IRCMessageType = 441
ErrNotOnChannel MessageType = 442 ErrNotOnChannel IRCMessageType = 442
ErrUserOnChannel MessageType = 443 ErrUserOnChannel IRCMessageType = 443
ErrNoLogin MessageType = 444 ErrNoLogin IRCMessageType = 444
ErrSummonDisabled MessageType = 445 ErrSummonDisabled IRCMessageType = 445
ErrUsersDisabled MessageType = 446 ErrUsersDisabled IRCMessageType = 446
ErrNotRegistered MessageType = 451 ErrNotRegistered IRCMessageType = 451
ErrNeedMoreParams MessageType = 461 ErrNeedMoreParams IRCMessageType = 461
ErrAlreadyRegistered MessageType = 462 ErrAlreadyRegistered IRCMessageType = 462
ErrNoPermForHost MessageType = 463 ErrNoPermForHost IRCMessageType = 463
ErrPasswdMismatch MessageType = 464 ErrPasswdMismatch IRCMessageType = 464
ErrYoureBannedCreep MessageType = 465 ErrYoureBannedCreep IRCMessageType = 465
ErrYouWillBeBanned MessageType = 466 ErrYouWillBeBanned IRCMessageType = 466
ErrKeySet MessageType = 467 ErrKeySet IRCMessageType = 467
ErrChannelIsFull MessageType = 471 ErrChannelIsFull IRCMessageType = 471
ErrUnknownMode MessageType = 472 ErrUnknownMode IRCMessageType = 472
ErrInviteOnlyChan MessageType = 473 ErrInviteOnlyChan IRCMessageType = 473
ErrBannedFromChan MessageType = 474 ErrBannedFromChan IRCMessageType = 474
ErrBadChannelKey MessageType = 475 ErrBadChannelKey IRCMessageType = 475
ErrBadChanMask MessageType = 476 ErrBadChanMask IRCMessageType = 476
ErrNoChanModes MessageType = 477 ErrNoChanModes IRCMessageType = 477
ErrBanListFull MessageType = 478 ErrBanListFull IRCMessageType = 478
ErrNoPrivileges MessageType = 481 ErrNoPrivileges IRCMessageType = 481
ErrChanOpPrivsNeeded MessageType = 482 ErrChanOpPrivsNeeded IRCMessageType = 482
ErrCantKillServer MessageType = 483 ErrCantKillServer IRCMessageType = 483
ErrRestricted MessageType = 484 ErrRestricted IRCMessageType = 484
ErrUniqOpPrivsNeeded MessageType = 485 ErrUniqOpPrivsNeeded IRCMessageType = 485
ErrNoOperHost MessageType = 491 ErrNoOperHost IRCMessageType = 491
ErrUmodeUnknownFlag MessageType = 501 ErrUmodeUnknownFlag IRCMessageType = 501
ErrUsersDoNotMatch MessageType = 502 ErrUsersDoNotMatch IRCMessageType = 502
) )
// names maps numeric codes to their standard IRC names. // names maps numeric codes to their standard IRC names.
// //
//nolint:gochecknoglobals //nolint:gochecknoglobals
var names = map[MessageType]string{ var names = map[IRCMessageType]string{
RplWelcome: "RPL_WELCOME", RplWelcome: "RPL_WELCOME",
RplYourHost: "RPL_YOURHOST", RplYourHost: "RPL_YOURHOST",
RplCreated: "RPL_CREATED", RplCreated: "RPL_CREATED",
@@ -350,6 +384,8 @@ var names = map[MessageType]string{
// Name returns the standard IRC name for a numeric code // Name returns the standard IRC name for a numeric code
// (e.g., Name(2) returns "RPL_YOURHOST"). Returns an // (e.g., Name(2) returns "RPL_YOURHOST"). Returns an
// empty string if the code is unknown. // empty string if the code is unknown.
func Name(code MessageType) string { //
// Deprecated: Use IRCMessageType.Name() instead.
func Name(code IRCMessageType) string {
return names[code] return names[code]
} }