@@ -90,26 +90,30 @@ pub fn write_nil<W: RmpWrite>(wr: &mut W) -> Result<(), W::Error> {
9090///
9191/// According to the MessagePack specification, a timestamp value is represented as a 32, 64, or 96 bit Extension struct.
9292///
93+ /// This will return `Ok(false)` if the timestamp contained a value that is invalid for the msgpack spec.
94+ /// When `Ok(false)` is returned, nothing has been written to the writer.
95+ ///
9396/// # Errors
9497///
9598/// This function will return `Error` on any I/O error occurred while writing the timestamp.
9699///
97100/// # Examples
98101///
99102/// ```
103+ /// use chrono::DateTime;
100104/// use rmp::Timestamp;
101105///
102106/// let mut buf1 = Vec::new();
103107/// let mut buf2 = Vec::new();
104108/// let mut buf3 = Vec::new();
105109///
106- /// let ts1 = Timestamp::T32 { secs: 0x66c1de7c } ;
107- /// let ts2 = Timestamp::T64 { nsecs: 0x3b9ac9ff, secs: 0x66c1de7c } ;
108- /// let ts3 = Timestamp::T96 { nsecs: 0x3b9ac9ff, secs: 0x66c1de7c } ;
110+ /// let ts1 = Timestamp::T32(DateTime::from_timestamp( 0x66c1de7c, 0).unwrap()) ;
111+ /// let ts2 = Timestamp::T64(DateTime::from_timestamp( 0x66c1de7c, 0x3b9ac9ff).unwrap()) ;
112+ /// let ts3 = Timestamp::T96(DateTime::from_timestamp( 0x66c1de7c, 0x3b9ac9ff).unwrap()) ;
109113///
110- /// rmp::encode::write_timestamp(&mut buf1, ts1).ok();
111- /// rmp::encode::write_timestamp(&mut buf2, ts2).ok();
112- /// rmp::encode::write_timestamp(&mut buf3, ts3).ok();
114+ /// assert!( rmp::encode::write_timestamp(&mut buf1, ts1).ok().unwrap() );
115+ /// assert!( rmp::encode::write_timestamp(&mut buf2, ts2).ok().unwrap() );
116+ /// assert!( rmp::encode::write_timestamp(&mut buf3, ts3).ok().unwrap() );
113117///
114118/// // FixExt4 with a type of -1 (0xff)
115119/// assert_eq!(vec![0xd6, 0xff, 0x66, 0xc1, 0xde, 0x7c], buf1);
@@ -118,29 +122,44 @@ pub fn write_nil<W: RmpWrite>(wr: &mut W) -> Result<(), W::Error> {
118122/// // Ext8 with a size of 12 (0x0c) and a type of -1 (0xff)
119123/// assert_eq!(vec![0xc7, 0x0c, 0xff, 0x3b, 0x9a, 0xc9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x66, 0xc1, 0xde, 0x7c], buf3);
120124/// ```
125+ #[ cfg( feature = "chrono" ) ]
121126#[ inline]
122- pub fn write_timestamp < W : RmpWrite > ( wr : & mut W , timestamp : Timestamp ) -> Result < ( ) , DataWriteError < W :: Error > > {
127+ pub fn write_timestamp < W : RmpWrite > ( wr : & mut W , timestamp : Timestamp ) -> Result < bool , DataWriteError < W :: Error > > {
123128 match timestamp {
124- Timestamp :: T32 { secs } => {
129+ Timestamp :: T32 ( timedate) => {
130+ let secs = timedate. timestamp ( ) ;
131+ if secs < 0 || secs > u32:: MAX as i64 {
132+ return Ok ( false )
133+ }
125134 write_marker ( wr, Marker :: FixExt4 ) . map_err ( |e| e. 0 ) ?;
126135 wr. write_data_i8 ( -1 ) ?;
127136 wr. write_data_u32 ( secs as u32 ) ?;
128137 } ,
129- Timestamp :: T64 { nsecs, secs } => {
138+ Timestamp :: T64 ( timedate) => {
139+ let secs = timedate. timestamp ( ) ;
140+ let nsecs = timedate. timestamp_subsec_nanos ( ) ;
141+ if secs < 0 || secs > 0x3_ffff_ffff || nsecs > crate :: MAX_NSECS {
142+ return Ok ( false )
143+ }
130144 write_marker ( wr, Marker :: FixExt8 ) . map_err ( |e| e. 0 ) ?;
131145 let data = ( ( nsecs as u64 ) << 34 ) | ( secs as u64 ) ;
132146 wr. write_data_i8 ( -1 ) ?;
133147 wr. write_data_u64 ( data) ?;
134148 } ,
135- Timestamp :: T96 { nsecs, secs } => {
149+ Timestamp :: T96 ( timedate) => {
150+ let secs = timedate. timestamp ( ) ;
151+ let nsecs = timedate. timestamp_subsec_nanos ( ) ;
152+ if nsecs > crate :: MAX_NSECS {
153+ return Ok ( false )
154+ }
136155 write_marker ( wr, Marker :: Ext8 ) . map_err ( |e| e. 0 ) ?;
137156 wr. write_data_u8 ( 12 ) ?;
138157 wr. write_data_i8 ( -1 ) ?;
139158 wr. write_data_u32 ( nsecs) ?;
140159 wr. write_data_i64 ( secs) ?;
141160 } ,
142161 }
143- Ok ( ( ) )
162+ Ok ( true )
144163}
145164
146165/// Encodes and attempts to write a bool value into the given write.
0 commit comments