1 //! Implementations of `ProtobufType` for all types. 2 3 use std::marker; 4 use std::mem; 5 6 #[cfg(feature = "bytes")] 7 use crate::chars::Chars; 8 #[cfg(feature = "bytes")] 9 use bytes::Bytes; 10 11 use crate::coded_input_stream::CodedInputStream; 12 use crate::coded_output_stream::CodedOutputStream; 13 use crate::enums::ProtobufEnum; 14 use crate::error::ProtobufResult; 15 use crate::message::Message; 16 use crate::reflect::ProtobufValue; 17 use crate::rt; 18 use crate::unknown::UnknownValues; 19 use crate::wire_format::WireType; 20 use crate::zigzag::decode_zig_zag_32; 21 use crate::zigzag::decode_zig_zag_64; 22 23 /// Protobuf elementary type as generic trait 24 pub trait ProtobufType { 25 /// Rust type of value 26 type Value: ProtobufValue + Clone + 'static; 27 28 /// Wire type when writing to stream wire_type() -> WireType29 fn wire_type() -> WireType; 30 31 /// Read value from `CodedInputStream` read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>32 fn read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>; 33 34 /// Compute wire size compute_size(value: &Self::Value) -> u3235 fn compute_size(value: &Self::Value) -> u32; 36 37 /// Get value from `UnknownValues` get_from_unknown(unknown_values: &UnknownValues) -> Option<Self::Value>38 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Self::Value>; 39 40 /// Compute size adding length prefix if wire type is length delimited 41 /// (i. e. string, bytes, message) compute_size_with_length_delimiter(value: &Self::Value) -> u3242 fn compute_size_with_length_delimiter(value: &Self::Value) -> u32 { 43 let size = Self::compute_size(value); 44 if Self::wire_type() == WireType::WireTypeLengthDelimited { 45 rt::compute_raw_varint32_size(size) + size 46 } else { 47 size 48 } 49 } 50 51 /// Get previously computed size 52 #[inline] get_cached_size(value: &Self::Value) -> u3253 fn get_cached_size(value: &Self::Value) -> u32 { 54 Self::compute_size(value) 55 } 56 57 /// Get previously cached size with length prefix 58 #[inline] get_cached_size_with_length_delimiter(value: &Self::Value) -> u3259 fn get_cached_size_with_length_delimiter(value: &Self::Value) -> u32 { 60 let size = Self::get_cached_size(value); 61 if Self::wire_type() == WireType::WireTypeLengthDelimited { 62 rt::compute_raw_varint32_size(size) + size 63 } else { 64 size 65 } 66 } 67 68 /// Write a value with previously cached size write_with_cached_size( field_number: u32, value: &Self::Value, os: &mut CodedOutputStream, ) -> ProtobufResult<()>69 fn write_with_cached_size( 70 field_number: u32, 71 value: &Self::Value, 72 os: &mut CodedOutputStream, 73 ) -> ProtobufResult<()>; 74 } 75 76 /// `float` 77 pub struct ProtobufTypeFloat; 78 /// `double` 79 pub struct ProtobufTypeDouble; 80 /// `uint32` 81 pub struct ProtobufTypeInt32; 82 /// `int64` 83 pub struct ProtobufTypeInt64; 84 /// `uint32` 85 pub struct ProtobufTypeUint32; 86 /// `uint64` 87 pub struct ProtobufTypeUint64; 88 /// `sint32` 89 pub struct ProtobufTypeSint32; 90 /// `sint64` 91 pub struct ProtobufTypeSint64; 92 /// `fixed32` 93 pub struct ProtobufTypeFixed32; 94 /// `fixed64` 95 pub struct ProtobufTypeFixed64; 96 /// `sfixed32` 97 pub struct ProtobufTypeSfixed32; 98 /// `sfixed64` 99 pub struct ProtobufTypeSfixed64; 100 /// `bool` 101 pub struct ProtobufTypeBool; 102 /// `string` 103 pub struct ProtobufTypeString; 104 /// `bytes` 105 pub struct ProtobufTypeBytes; 106 /// Something which should be deleted 107 pub struct ProtobufTypeChars; 108 109 /// `bytes` as [`Bytes`](bytes::Bytes) 110 #[cfg(feature = "bytes")] 111 pub struct ProtobufTypeCarllercheBytes; 112 /// `string` as [`Chars`](crate::Chars) 113 #[cfg(feature = "bytes")] 114 pub struct ProtobufTypeCarllercheChars; 115 116 /// `enum` 117 pub struct ProtobufTypeEnum<E: ProtobufEnum>(marker::PhantomData<E>); 118 /// `message` 119 pub struct ProtobufTypeMessage<M: Message>(marker::PhantomData<M>); 120 121 impl ProtobufType for ProtobufTypeFloat { 122 type Value = f32; 123 wire_type() -> WireType124 fn wire_type() -> WireType { 125 WireType::WireTypeFixed32 126 } 127 read(is: &mut CodedInputStream) -> ProtobufResult<f32>128 fn read(is: &mut CodedInputStream) -> ProtobufResult<f32> { 129 is.read_float() 130 } 131 compute_size(_value: &f32) -> u32132 fn compute_size(_value: &f32) -> u32 { 133 4 134 } 135 get_from_unknown(unknown_values: &UnknownValues) -> Option<f32>136 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<f32> { 137 unknown_values 138 .fixed32 139 .iter() 140 .rev() 141 .next() 142 .map(|&bits| unsafe { mem::transmute::<u32, f32>(bits) }) 143 } 144 write_with_cached_size( field_number: u32, value: &f32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>145 fn write_with_cached_size( 146 field_number: u32, 147 value: &f32, 148 os: &mut CodedOutputStream, 149 ) -> ProtobufResult<()> { 150 os.write_float(field_number, *value) 151 } 152 } 153 154 impl ProtobufType for ProtobufTypeDouble { 155 type Value = f64; 156 wire_type() -> WireType157 fn wire_type() -> WireType { 158 WireType::WireTypeFixed64 159 } 160 read(is: &mut CodedInputStream) -> ProtobufResult<f64>161 fn read(is: &mut CodedInputStream) -> ProtobufResult<f64> { 162 is.read_double() 163 } 164 get_from_unknown(unknown_values: &UnknownValues) -> Option<f64>165 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<f64> { 166 unknown_values 167 .fixed64 168 .iter() 169 .rev() 170 .next() 171 .map(|&bits| unsafe { mem::transmute::<u64, f64>(bits) }) 172 } 173 compute_size(_value: &f64) -> u32174 fn compute_size(_value: &f64) -> u32 { 175 8 176 } 177 write_with_cached_size( field_number: u32, value: &f64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>178 fn write_with_cached_size( 179 field_number: u32, 180 value: &f64, 181 os: &mut CodedOutputStream, 182 ) -> ProtobufResult<()> { 183 os.write_double(field_number, *value) 184 } 185 } 186 187 impl ProtobufType for ProtobufTypeInt32 { 188 type Value = i32; 189 wire_type() -> WireType190 fn wire_type() -> WireType { 191 WireType::WireTypeVarint 192 } 193 read(is: &mut CodedInputStream) -> ProtobufResult<i32>194 fn read(is: &mut CodedInputStream) -> ProtobufResult<i32> { 195 is.read_int32() 196 } 197 compute_size(value: &i32) -> u32198 fn compute_size(value: &i32) -> u32 { 199 // See also: https://github.com/protocolbuffers/protobuf/blob/bd00671b924310c0353a730bf8fa77c44e0a9c72/src/google/protobuf/io/coded_stream.h#L1300-L1306 200 if *value < 0 { 201 return 10; 202 } 203 rt::compute_raw_varint32_size(*value as u32) 204 } 205 write_with_cached_size( field_number: u32, value: &i32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>206 fn write_with_cached_size( 207 field_number: u32, 208 value: &i32, 209 os: &mut CodedOutputStream, 210 ) -> ProtobufResult<()> { 211 os.write_int32(field_number, *value) 212 } 213 get_from_unknown(unknown_values: &UnknownValues) -> Option<i32>214 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i32> { 215 unknown_values.varint.iter().rev().next().map(|&v| v as i32) 216 } 217 } 218 219 impl ProtobufType for ProtobufTypeInt64 { 220 type Value = i64; 221 wire_type() -> WireType222 fn wire_type() -> WireType { 223 WireType::WireTypeVarint 224 } 225 read(is: &mut CodedInputStream) -> ProtobufResult<i64>226 fn read(is: &mut CodedInputStream) -> ProtobufResult<i64> { 227 is.read_int64() 228 } 229 get_from_unknown(unknown_values: &UnknownValues) -> Option<i64>230 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i64> { 231 unknown_values.varint.iter().rev().next().map(|&v| v as i64) 232 } 233 compute_size(value: &i64) -> u32234 fn compute_size(value: &i64) -> u32 { 235 rt::compute_raw_varint64_size(*value as u64) 236 } 237 write_with_cached_size( field_number: u32, value: &i64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>238 fn write_with_cached_size( 239 field_number: u32, 240 value: &i64, 241 os: &mut CodedOutputStream, 242 ) -> ProtobufResult<()> { 243 os.write_int64(field_number, *value) 244 } 245 } 246 247 impl ProtobufType for ProtobufTypeUint32 { 248 type Value = u32; 249 wire_type() -> WireType250 fn wire_type() -> WireType { 251 WireType::WireTypeVarint 252 } 253 read(is: &mut CodedInputStream) -> ProtobufResult<u32>254 fn read(is: &mut CodedInputStream) -> ProtobufResult<u32> { 255 is.read_uint32() 256 } 257 get_from_unknown(unknown_values: &UnknownValues) -> Option<u32>258 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u32> { 259 unknown_values.varint.iter().rev().next().map(|&v| v as u32) 260 } 261 compute_size(value: &u32) -> u32262 fn compute_size(value: &u32) -> u32 { 263 rt::compute_raw_varint32_size(*value) 264 } 265 write_with_cached_size( field_number: u32, value: &u32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>266 fn write_with_cached_size( 267 field_number: u32, 268 value: &u32, 269 os: &mut CodedOutputStream, 270 ) -> ProtobufResult<()> { 271 os.write_uint32(field_number, *value) 272 } 273 } 274 275 impl ProtobufType for ProtobufTypeUint64 { 276 type Value = u64; 277 wire_type() -> WireType278 fn wire_type() -> WireType { 279 WireType::WireTypeVarint 280 } 281 read(is: &mut CodedInputStream) -> ProtobufResult<u64>282 fn read(is: &mut CodedInputStream) -> ProtobufResult<u64> { 283 is.read_uint64() 284 } 285 get_from_unknown(unknown_values: &UnknownValues) -> Option<u64>286 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u64> { 287 unknown_values.varint.iter().cloned().rev().next() 288 } 289 compute_size(value: &u64) -> u32290 fn compute_size(value: &u64) -> u32 { 291 rt::compute_raw_varint64_size(*value) 292 } 293 write_with_cached_size( field_number: u32, value: &u64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>294 fn write_with_cached_size( 295 field_number: u32, 296 value: &u64, 297 os: &mut CodedOutputStream, 298 ) -> ProtobufResult<()> { 299 os.write_uint64(field_number, *value) 300 } 301 } 302 303 impl ProtobufType for ProtobufTypeSint32 { 304 type Value = i32; 305 wire_type() -> WireType306 fn wire_type() -> WireType { 307 WireType::WireTypeVarint 308 } 309 read(is: &mut CodedInputStream) -> ProtobufResult<i32>310 fn read(is: &mut CodedInputStream) -> ProtobufResult<i32> { 311 is.read_sint32() 312 } 313 get_from_unknown(unknown_values: &UnknownValues) -> Option<i32>314 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i32> { 315 ProtobufTypeUint32::get_from_unknown(unknown_values).map(decode_zig_zag_32) 316 } 317 compute_size(value: &i32) -> u32318 fn compute_size(value: &i32) -> u32 { 319 rt::value_varint_zigzag_size_no_tag(*value) 320 } 321 write_with_cached_size( field_number: u32, value: &i32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>322 fn write_with_cached_size( 323 field_number: u32, 324 value: &i32, 325 os: &mut CodedOutputStream, 326 ) -> ProtobufResult<()> { 327 os.write_sint32(field_number, *value) 328 } 329 } 330 331 impl ProtobufType for ProtobufTypeSint64 { 332 type Value = i64; 333 wire_type() -> WireType334 fn wire_type() -> WireType { 335 WireType::WireTypeVarint 336 } 337 read(is: &mut CodedInputStream) -> ProtobufResult<i64>338 fn read(is: &mut CodedInputStream) -> ProtobufResult<i64> { 339 is.read_sint64() 340 } 341 get_from_unknown(unknown_values: &UnknownValues) -> Option<i64>342 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i64> { 343 ProtobufTypeUint64::get_from_unknown(unknown_values).map(decode_zig_zag_64) 344 } 345 compute_size(value: &i64) -> u32346 fn compute_size(value: &i64) -> u32 { 347 rt::value_varint_zigzag_size_no_tag(*value) 348 } 349 write_with_cached_size( field_number: u32, value: &i64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>350 fn write_with_cached_size( 351 field_number: u32, 352 value: &i64, 353 os: &mut CodedOutputStream, 354 ) -> ProtobufResult<()> { 355 os.write_sint64(field_number, *value) 356 } 357 } 358 359 impl ProtobufType for ProtobufTypeFixed32 { 360 type Value = u32; 361 wire_type() -> WireType362 fn wire_type() -> WireType { 363 WireType::WireTypeFixed32 364 } 365 read(is: &mut CodedInputStream) -> ProtobufResult<u32>366 fn read(is: &mut CodedInputStream) -> ProtobufResult<u32> { 367 is.read_fixed32() 368 } 369 get_from_unknown(unknown_values: &UnknownValues) -> Option<u32>370 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u32> { 371 unknown_values.fixed32.iter().cloned().rev().next() 372 } 373 compute_size(_value: &u32) -> u32374 fn compute_size(_value: &u32) -> u32 { 375 4 376 } 377 write_with_cached_size( field_number: u32, value: &u32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>378 fn write_with_cached_size( 379 field_number: u32, 380 value: &u32, 381 os: &mut CodedOutputStream, 382 ) -> ProtobufResult<()> { 383 os.write_fixed32(field_number, *value) 384 } 385 } 386 387 impl ProtobufType for ProtobufTypeFixed64 { 388 type Value = u64; 389 wire_type() -> WireType390 fn wire_type() -> WireType { 391 WireType::WireTypeFixed64 392 } 393 read(is: &mut CodedInputStream) -> ProtobufResult<u64>394 fn read(is: &mut CodedInputStream) -> ProtobufResult<u64> { 395 is.read_fixed64() 396 } 397 get_from_unknown(unknown_values: &UnknownValues) -> Option<u64>398 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<u64> { 399 unknown_values.fixed64.iter().cloned().rev().next() 400 } 401 compute_size(_value: &u64) -> u32402 fn compute_size(_value: &u64) -> u32 { 403 8 404 } 405 write_with_cached_size( field_number: u32, value: &u64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>406 fn write_with_cached_size( 407 field_number: u32, 408 value: &u64, 409 os: &mut CodedOutputStream, 410 ) -> ProtobufResult<()> { 411 os.write_fixed64(field_number, *value) 412 } 413 } 414 415 impl ProtobufType for ProtobufTypeSfixed32 { 416 type Value = i32; 417 wire_type() -> WireType418 fn wire_type() -> WireType { 419 WireType::WireTypeFixed32 420 } 421 read(is: &mut CodedInputStream) -> ProtobufResult<i32>422 fn read(is: &mut CodedInputStream) -> ProtobufResult<i32> { 423 is.read_sfixed32() 424 } 425 get_from_unknown(unknown_values: &UnknownValues) -> Option<i32>426 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i32> { 427 ProtobufTypeFixed32::get_from_unknown(unknown_values).map(|u| u as i32) 428 } 429 compute_size(_value: &i32) -> u32430 fn compute_size(_value: &i32) -> u32 { 431 4 432 } 433 write_with_cached_size( field_number: u32, value: &i32, os: &mut CodedOutputStream, ) -> ProtobufResult<()>434 fn write_with_cached_size( 435 field_number: u32, 436 value: &i32, 437 os: &mut CodedOutputStream, 438 ) -> ProtobufResult<()> { 439 os.write_sfixed32(field_number, *value) 440 } 441 } 442 443 impl ProtobufType for ProtobufTypeSfixed64 { 444 type Value = i64; 445 wire_type() -> WireType446 fn wire_type() -> WireType { 447 WireType::WireTypeFixed64 448 } 449 read(is: &mut CodedInputStream) -> ProtobufResult<i64>450 fn read(is: &mut CodedInputStream) -> ProtobufResult<i64> { 451 is.read_sfixed64() 452 } 453 get_from_unknown(unknown_values: &UnknownValues) -> Option<i64>454 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<i64> { 455 ProtobufTypeFixed64::get_from_unknown(unknown_values).map(|u| u as i64) 456 } 457 compute_size(_value: &i64) -> u32458 fn compute_size(_value: &i64) -> u32 { 459 8 460 } 461 write_with_cached_size( field_number: u32, value: &i64, os: &mut CodedOutputStream, ) -> ProtobufResult<()>462 fn write_with_cached_size( 463 field_number: u32, 464 value: &i64, 465 os: &mut CodedOutputStream, 466 ) -> ProtobufResult<()> { 467 os.write_sfixed64(field_number, *value) 468 } 469 } 470 471 impl ProtobufType for ProtobufTypeBool { 472 type Value = bool; 473 wire_type() -> WireType474 fn wire_type() -> WireType { 475 WireType::WireTypeVarint 476 } 477 read(is: &mut CodedInputStream) -> ProtobufResult<bool>478 fn read(is: &mut CodedInputStream) -> ProtobufResult<bool> { 479 is.read_bool() 480 } 481 get_from_unknown(unknown: &UnknownValues) -> Option<bool>482 fn get_from_unknown(unknown: &UnknownValues) -> Option<bool> { 483 unknown.varint.iter().rev().next().map(|&v| v != 0) 484 } 485 compute_size(_value: &bool) -> u32486 fn compute_size(_value: &bool) -> u32 { 487 1 488 } 489 write_with_cached_size( field_number: u32, value: &bool, os: &mut CodedOutputStream, ) -> ProtobufResult<()>490 fn write_with_cached_size( 491 field_number: u32, 492 value: &bool, 493 os: &mut CodedOutputStream, 494 ) -> ProtobufResult<()> { 495 os.write_bool(field_number, *value) 496 } 497 } 498 499 impl ProtobufType for ProtobufTypeString { 500 type Value = String; 501 wire_type() -> WireType502 fn wire_type() -> WireType { 503 WireType::WireTypeLengthDelimited 504 } 505 read(is: &mut CodedInputStream) -> ProtobufResult<String>506 fn read(is: &mut CodedInputStream) -> ProtobufResult<String> { 507 is.read_string() 508 } 509 get_from_unknown(unknown_values: &UnknownValues) -> Option<String>510 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<String> { 511 // TODO: should not panic 512 ProtobufTypeBytes::get_from_unknown(unknown_values) 513 .map(|b| String::from_utf8(b).expect("not a valid string")) 514 } 515 compute_size(value: &String) -> u32516 fn compute_size(value: &String) -> u32 { 517 value.len() as u32 518 } 519 write_with_cached_size( field_number: u32, value: &String, os: &mut CodedOutputStream, ) -> ProtobufResult<()>520 fn write_with_cached_size( 521 field_number: u32, 522 value: &String, 523 os: &mut CodedOutputStream, 524 ) -> ProtobufResult<()> { 525 os.write_string(field_number, &value) 526 } 527 } 528 529 impl ProtobufType for ProtobufTypeBytes { 530 type Value = Vec<u8>; 531 wire_type() -> WireType532 fn wire_type() -> WireType { 533 WireType::WireTypeLengthDelimited 534 } 535 read(is: &mut CodedInputStream) -> ProtobufResult<Vec<u8>>536 fn read(is: &mut CodedInputStream) -> ProtobufResult<Vec<u8>> { 537 is.read_bytes() 538 } 539 get_from_unknown(unknown_values: &UnknownValues) -> Option<Vec<u8>>540 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Vec<u8>> { 541 unknown_values.length_delimited.iter().cloned().rev().next() 542 } 543 compute_size(value: &Vec<u8>) -> u32544 fn compute_size(value: &Vec<u8>) -> u32 { 545 value.len() as u32 546 } 547 write_with_cached_size( field_number: u32, value: &Vec<u8>, os: &mut CodedOutputStream, ) -> ProtobufResult<()>548 fn write_with_cached_size( 549 field_number: u32, 550 value: &Vec<u8>, 551 os: &mut CodedOutputStream, 552 ) -> ProtobufResult<()> { 553 os.write_bytes(field_number, &value) 554 } 555 } 556 557 #[cfg(feature = "bytes")] 558 impl ProtobufType for ProtobufTypeCarllercheBytes { 559 type Value = Bytes; 560 wire_type() -> WireType561 fn wire_type() -> WireType { 562 ProtobufTypeBytes::wire_type() 563 } 564 read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>565 fn read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value> { 566 is.read_carllerche_bytes() 567 } 568 get_from_unknown(unknown_values: &UnknownValues) -> Option<Bytes>569 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Bytes> { 570 ProtobufTypeBytes::get_from_unknown(unknown_values).map(Bytes::from) 571 } 572 compute_size(value: &Bytes) -> u32573 fn compute_size(value: &Bytes) -> u32 { 574 value.len() as u32 575 } 576 write_with_cached_size( field_number: u32, value: &Bytes, os: &mut CodedOutputStream, ) -> ProtobufResult<()>577 fn write_with_cached_size( 578 field_number: u32, 579 value: &Bytes, 580 os: &mut CodedOutputStream, 581 ) -> ProtobufResult<()> { 582 os.write_bytes(field_number, &value) 583 } 584 } 585 586 #[cfg(feature = "bytes")] 587 impl ProtobufType for ProtobufTypeCarllercheChars { 588 type Value = Chars; 589 wire_type() -> WireType590 fn wire_type() -> WireType { 591 ProtobufTypeBytes::wire_type() 592 } 593 read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value>594 fn read(is: &mut CodedInputStream) -> ProtobufResult<Self::Value> { 595 is.read_carllerche_chars() 596 } 597 get_from_unknown(unknown_values: &UnknownValues) -> Option<Chars>598 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<Chars> { 599 ProtobufTypeString::get_from_unknown(unknown_values).map(Chars::from) 600 } 601 compute_size(value: &Chars) -> u32602 fn compute_size(value: &Chars) -> u32 { 603 value.len() as u32 604 } 605 write_with_cached_size( field_number: u32, value: &Chars, os: &mut CodedOutputStream, ) -> ProtobufResult<()>606 fn write_with_cached_size( 607 field_number: u32, 608 value: &Chars, 609 os: &mut CodedOutputStream, 610 ) -> ProtobufResult<()> { 611 os.write_string(field_number, &value) 612 } 613 } 614 615 impl<E: ProtobufEnum + ProtobufValue> ProtobufType for ProtobufTypeEnum<E> { 616 type Value = E; 617 wire_type() -> WireType618 fn wire_type() -> WireType { 619 WireType::WireTypeVarint 620 } 621 read(is: &mut CodedInputStream) -> ProtobufResult<E>622 fn read(is: &mut CodedInputStream) -> ProtobufResult<E> { 623 is.read_enum() 624 } 625 get_from_unknown(unknown_values: &UnknownValues) -> Option<E>626 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<E> { 627 // TODO: do not panic 628 ProtobufTypeInt32::get_from_unknown(unknown_values) 629 .map(|i| E::from_i32(i).expect("not a valid enum value")) 630 } 631 compute_size(value: &E) -> u32632 fn compute_size(value: &E) -> u32 { 633 rt::compute_raw_varint32_size(value.value() as u32) // TODO: wrap 634 } 635 write_with_cached_size( field_number: u32, value: &E, os: &mut CodedOutputStream, ) -> ProtobufResult<()>636 fn write_with_cached_size( 637 field_number: u32, 638 value: &E, 639 os: &mut CodedOutputStream, 640 ) -> ProtobufResult<()> { 641 os.write_enum_obj(field_number, *value) 642 } 643 } 644 645 impl<M: Message + Clone + ProtobufValue> ProtobufType for ProtobufTypeMessage<M> { 646 type Value = M; 647 wire_type() -> WireType648 fn wire_type() -> WireType { 649 WireType::WireTypeLengthDelimited 650 } 651 read(is: &mut CodedInputStream) -> ProtobufResult<M>652 fn read(is: &mut CodedInputStream) -> ProtobufResult<M> { 653 is.read_message() 654 } 655 get_from_unknown(unknown_values: &UnknownValues) -> Option<M>656 fn get_from_unknown(unknown_values: &UnknownValues) -> Option<M> { 657 // TODO: do not panic 658 unknown_values 659 .length_delimited 660 .iter() 661 .rev() 662 .next() 663 .map(|bytes| M::parse_from_bytes(bytes).expect("cannot parse message")) 664 } 665 compute_size(value: &M) -> u32666 fn compute_size(value: &M) -> u32 { 667 value.compute_size() 668 } 669 get_cached_size(value: &M) -> u32670 fn get_cached_size(value: &M) -> u32 { 671 value.get_cached_size() 672 } 673 write_with_cached_size( field_number: u32, value: &Self::Value, os: &mut CodedOutputStream, ) -> ProtobufResult<()>674 fn write_with_cached_size( 675 field_number: u32, 676 value: &Self::Value, 677 os: &mut CodedOutputStream, 678 ) -> ProtobufResult<()> { 679 os.write_tag(field_number, WireType::WireTypeLengthDelimited)?; 680 os.write_raw_varint32(value.get_cached_size())?; 681 value.write_to_with_cached_sizes(os)?; 682 Ok(()) 683 } 684 } 685