Skip to content

Commit 2a65f2b

Browse files
authored
Add ChannelCore.tryUnwrapAs (#1919)
Motivation: For Channel implementations, we implemented ChannelCore.unwrapData to allow them to unwrap a NIOAny into their expected data type. This remains our recommended flow, as Channels are supposed to know what data type they can send. However, in a few cases the Channel has a runtime type: in particular, EmbeddedChannel is capable of tolerating nearly anything. As we're coming to split the code apart, we'll likely want EmbeddedChannel to live in a different module than NIOCore. To that end, we need to add new API to ChannelCore to allow the specific EmbeddedChannel use-case. Modifications: - Implement ChannelCore.tryUnwrapData. - Use this within EmbeddedChannel. Result: EmbeddedChannel can attempt to unwrap things.
1 parent 8b06e8f commit 2a65f2b

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

Sources/NIO/Channel.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,28 @@ extension ChannelCore {
301301
return data.forceAs()
302302
}
303303

304+
/// Attempts to unwrap the given `NIOAny` as a specific concrete type.
305+
///
306+
/// This method is intended for use when writing custom `ChannelCore` implementations.
307+
/// This can safely be called in methods like `write0` to extract data from the `NIOAny`
308+
/// provided in those cases.
309+
///
310+
/// If the unwrap fails, this will return `nil`. `ChannelCore` implementations should almost
311+
/// always support only one runtime type, so in general they should avoid using this and prefer
312+
/// using `unwrapData` instead. This method exists for rare use-cases where tolerating type
313+
/// mismatches is acceptable.
314+
///
315+
/// - parameters:
316+
/// - data: The `NIOAny` to unwrap.
317+
/// - as: The type to extract from the `NIOAny`.
318+
/// - returns: The content of the `NIOAny`, or `nil` if the type is incorrect.
319+
/// - warning: If you are implementing a `ChannelCore`, you should use `unwrapData` unless you
320+
/// are doing something _extremely_ unusual.
321+
@inlinable
322+
public func tryUnwrapData<T>(_ data: NIOAny, as: T.Type = T.self) -> T? {
323+
return data.tryAs()
324+
}
325+
304326
/// Removes the `ChannelHandler`s from the `ChannelPipeline` belonging to `channel`, and
305327
/// closes that `ChannelPipeline`.
306328
///

Sources/NIO/Embedded.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ public final class EmbeddedChannel: Channel {
630630
return nil
631631
}
632632
let elem = buffer.removeFirst()
633-
guard let t = elem.tryAs(type: T.self) else {
633+
guard let t = self._channelCore.tryUnwrapData(elem, as: T.self) else {
634634
throw WrongTypeError(expected: T.self, actual: type(of: elem.forceAs(type: Any.self)))
635635
}
636636
return t

0 commit comments

Comments
 (0)