33use std:: io;
44
55use bytes:: BytesMut ;
6+ #[ cfg( feature = "encoding" ) ]
67use encoding:: label:: encoding_from_whatwg_label;
8+ #[ cfg( feature = "encoding" ) ]
79use encoding:: { DecoderTrap , EncoderTrap , EncodingRef } ;
810use tokio_util:: codec:: { Decoder , Encoder } ;
911
1012use crate :: error;
1113
1214/// A line-based codec parameterized by an encoding.
1315pub struct LineCodec {
16+ #[ cfg( feature = "encoding" ) ]
1417 encoding : EncodingRef ,
1518 next_index : usize ,
1619}
1720
1821impl LineCodec {
1922 /// Creates a new instance of LineCodec from the specified encoding.
2023 pub fn new ( label : & str ) -> error:: Result < LineCodec > {
21- encoding_from_whatwg_label ( label)
22- . map ( |enc| LineCodec {
23- encoding : enc,
24- next_index : 0 ,
25- } )
26- . ok_or_else ( || {
27- io:: Error :: new (
28- io:: ErrorKind :: InvalidInput ,
29- & format ! ( "Attempted to use unknown codec {}." , label) [ ..] ,
30- )
31- . into ( )
32- } )
24+ Ok ( LineCodec {
25+ #[ cfg( feature = "encoding" ) ]
26+ encoding : match encoding_from_whatwg_label ( label) {
27+ Some ( x) => x,
28+ None => {
29+ return Err ( error:: ProtocolError :: Io ( io:: Error :: new (
30+ io:: ErrorKind :: InvalidInput ,
31+ & format ! ( "Attempted to use unknown codec {}." , label) [ ..] ,
32+ ) ) ) ;
33+ }
34+ } ,
35+ next_index : 0 ,
36+ } )
3337 }
3438}
3539
@@ -45,14 +49,29 @@ impl Decoder for LineCodec {
4549 // Set the search start index back to 0 since we found a newline.
4650 self . next_index = 0 ;
4751
48- // Decode the line using the codec's encoding.
49- match self . encoding . decode ( line. as_ref ( ) , DecoderTrap :: Replace ) {
50- Ok ( data) => Ok ( Some ( data) ) ,
51- Err ( data) => Err ( io:: Error :: new (
52- io:: ErrorKind :: InvalidInput ,
53- & format ! ( "Failed to decode {} as {}." , data, self . encoding. name( ) ) [ ..] ,
54- )
55- . into ( ) ) ,
52+ #[ cfg( feature = "encoding" ) ]
53+ {
54+ // Decode the line using the codec's encoding.
55+ match self . encoding . decode ( line. as_ref ( ) , DecoderTrap :: Replace ) {
56+ Ok ( data) => Ok ( Some ( data) ) ,
57+ Err ( data) => Err ( io:: Error :: new (
58+ io:: ErrorKind :: InvalidInput ,
59+ & format ! ( "Failed to decode {} as {}." , data, self . encoding. name( ) ) [ ..] ,
60+ )
61+ . into ( ) ) ,
62+ }
63+ }
64+
65+ #[ cfg( not( feature = "encoding" ) ) ]
66+ {
67+ match String :: from_utf8 ( line. to_vec ( ) ) {
68+ Ok ( data) => Ok ( Some ( data) ) ,
69+ Err ( data) => Err ( io:: Error :: new (
70+ io:: ErrorKind :: InvalidInput ,
71+ & format ! ( "Failed to decode {} as UTF-8." , data) [ ..] ,
72+ )
73+ . into ( ) ) ,
74+ }
5675 }
5776 } else {
5877 // Set the search start index to the current length since we know that none of the
@@ -67,20 +86,27 @@ impl Encoder<String> for LineCodec {
6786 type Error = error:: ProtocolError ;
6887
6988 fn encode ( & mut self , msg : String , dst : & mut BytesMut ) -> error:: Result < ( ) > {
70- // Encode the message using the codec's encoding.
71- let data: error:: Result < Vec < u8 > > = self
72- . encoding
73- . encode ( & msg, EncoderTrap :: Replace )
74- . map_err ( |data| {
75- io:: Error :: new (
76- io:: ErrorKind :: InvalidInput ,
77- & format ! ( "Failed to encode {} as {}." , data, self . encoding. name( ) ) [ ..] ,
78- )
79- . into ( )
80- } ) ;
89+ #[ cfg( feature = "encoding" ) ]
90+ {
91+ // Encode the message using the codec's encoding.
92+ let data: error:: Result < Vec < u8 > > = self
93+ . encoding
94+ . encode ( & msg, EncoderTrap :: Replace )
95+ . map_err ( |data| {
96+ io:: Error :: new (
97+ io:: ErrorKind :: InvalidInput ,
98+ & format ! ( "Failed to encode {} as {}." , data, self . encoding. name( ) ) [ ..] ,
99+ )
100+ . into ( )
101+ } ) ;
102+ // Write the encoded message to the output buffer.
103+ dst. extend ( & data?) ;
104+ }
81105
82- // Write the encoded message to the output buffer.
83- dst. extend ( & data?) ;
106+ #[ cfg( not( feature = "encoding" ) ) ]
107+ {
108+ dst. extend ( msg. into_bytes ( ) ) ;
109+ }
84110
85111 Ok ( ( ) )
86112 }
0 commit comments