-
Notifications
You must be signed in to change notification settings - Fork 6
Support optional message metadata tagged with @
(non-RFC)
#7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,7 @@ public struct IRCMessageParser { | |
// [':' SOURCE]? ' ' COMMAND [' ' ARGS]? [' :' LAST-ARG]? | ||
let cSpace : UInt8 = 32 | ||
let cColon : UInt8 = 58 | ||
let cAt : UInt8 = 64 | ||
let c0 : UInt8 = 48 + 0 | ||
let c9 : UInt8 = 48 + 9 | ||
guard !line.isEmpty else { throw Error.syntaxError } | ||
|
@@ -135,13 +136,37 @@ public struct IRCMessageParser { | |
return String(data: Data(slice), encoding: .utf8) // Sigh, the pain. | ||
} | ||
|
||
/* parse metadata */ | ||
|
||
let metadataSource : Swift.Slice<UnsafeRawBufferPointer>? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consistent indent w/ the rest would be nice :-) (I don't personally care too much about indentation styles, but they should be consistent within a project, which is 2-space right now in NIOIRC) |
||
|
||
if cursor[cursor.startIndex] == cAt { | ||
let startIndex = cursor.startIndex.advanced(by: 1) | ||
let spaceIdx = line.firstIndex(of: cSpace) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it safe to assume that the metadata itself doesn't contain spaces? Is there some escaping maybe? |
||
|
||
guard let endSourceIdx = spaceIdx, endSourceIdx > startIndex else { | ||
throw Error.invalidPrefix(Data(line)) | ||
} | ||
|
||
metadataSource = cursor[startIndex..<endSourceIdx] | ||
assert(!cursor.isEmpty) | ||
|
||
cursor = cursor[endSourceIdx..<cursor.endIndex] | ||
skipSpaces() | ||
} | ||
else { | ||
metadataSource = nil | ||
} | ||
|
||
/* parse source */ | ||
|
||
let source : Swift.Slice<UnsafeRawBufferPointer>? | ||
|
||
if cursor[cursor.startIndex] == cColon { | ||
// let spaceIdx = cursor.firstIndex(of: cSpace) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should probably remove such comments? :-) |
||
let startIndex = cursor.startIndex.advanced(by: 1) | ||
let spaceIdx = line.firstIndex(of: cSpace) | ||
// let spaceIdx = line.firstIndex(of: cSpace) | ||
let spaceIdx = cursor.firstIndex(of: cSpace) | ||
|
||
guard let endSourceIdx = spaceIdx, endSourceIdx > startIndex else { | ||
throw Error.invalidPrefix(Data(line)) | ||
|
@@ -159,7 +184,9 @@ public struct IRCMessageParser { | |
|
||
/* parse command name */ | ||
|
||
guard !cursor.isEmpty else { throw Error.invalidCommand(Data(line)) } | ||
guard !cursor.isEmpty else { | ||
throw Error.invalidCommand(Data(line)) | ||
} | ||
guard isLetter(cursor[cursor.startIndex]) | ||
|| isDigit(cursor[cursor.startIndex]) else { | ||
throw Error.invalidCommand(Data(line)) | ||
|
@@ -239,6 +266,16 @@ public struct IRCMessageParser { | |
|
||
/* construct */ | ||
|
||
let metadataString: String? | ||
if let metadataSource = metadataSource { | ||
guard let string = makeString(from: metadataSource) else { | ||
throw Error.invalidPrefix(Data(line)) | ||
} | ||
metadataString = string | ||
} else { | ||
metadataString = nil | ||
} | ||
|
||
let origin: String? | ||
if let source = source { | ||
guard let sourceString = makeString(from: source) else { | ||
|
@@ -252,10 +289,12 @@ public struct IRCMessageParser { | |
|
||
switch commandKey { | ||
case .string(let s): | ||
return IRCMessage(origin: origin, | ||
return IRCMessage(metadata: metadataString, | ||
origin: origin, | ||
command: try IRCCommand(s, arguments: args)) | ||
case .int(let i): | ||
return IRCMessage(origin: origin, | ||
return IRCMessage(metadata: metadataString, | ||
origin: origin, | ||
command: try IRCCommand(i, arguments: args)) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to keep the old API as well for backwards compat, i.e. the one taking no metadata. The default implementation of the one w/ metadata could call into the older method (vs raising notImplemented).