1 //! Structured values. 2 3 use std::fmt; 4 5 extern crate value_bag; 6 7 #[cfg(feature = "kv_unstable_sval")] 8 extern crate sval; 9 10 #[cfg(feature = "kv_unstable_serde")] 11 extern crate serde; 12 13 use self::value_bag::ValueBag; 14 15 pub use kv::Error; 16 17 /// A type that can be converted into a [`Value`](struct.Value.html). 18 pub trait ToValue { 19 /// Perform the conversion. to_value(&self) -> Value20 fn to_value(&self) -> Value; 21 } 22 23 impl<'a, T> ToValue for &'a T 24 where 25 T: ToValue + ?Sized, 26 { to_value(&self) -> Value27 fn to_value(&self) -> Value { 28 (**self).to_value() 29 } 30 } 31 32 impl<'v> ToValue for Value<'v> { to_value(&self) -> Value33 fn to_value(&self) -> Value { 34 Value { 35 inner: self.inner.clone(), 36 } 37 } 38 } 39 40 /// Get a value from a type implementing `std::fmt::Debug`. 41 #[macro_export] 42 macro_rules! as_debug { 43 ($capture:expr) => { 44 $crate::kv::Value::from_debug(&$capture) 45 }; 46 } 47 48 /// Get a value from a type implementing `std::fmt::Display`. 49 #[macro_export] 50 macro_rules! as_display { 51 ($capture:expr) => { 52 $crate::kv::Value::from_display(&$capture) 53 }; 54 } 55 56 /// Get a value from an error. 57 #[cfg(feature = "kv_unstable_std")] 58 #[macro_export] 59 macro_rules! as_error { 60 ($capture:expr) => { 61 $crate::kv::Value::from_dyn_error(&$capture) 62 }; 63 } 64 65 #[cfg(feature = "kv_unstable_serde")] 66 /// Get a value from a type implementing `serde::Serialize`. 67 #[macro_export] 68 macro_rules! as_serde { 69 ($capture:expr) => { 70 $crate::kv::Value::from_serde(&$capture) 71 }; 72 } 73 74 /// Get a value from a type implementing `sval::value::Value`. 75 #[cfg(feature = "kv_unstable_sval")] 76 #[macro_export] 77 macro_rules! as_sval { 78 ($capture:expr) => { 79 $crate::kv::Value::from_sval(&$capture) 80 }; 81 } 82 83 /// A value in a structured key-value pair. 84 /// 85 /// # Capturing values 86 /// 87 /// There are a few ways to capture a value: 88 /// 89 /// - Using the `Value::capture_*` methods. 90 /// - Using the `Value::from_*` methods. 91 /// - Using the `ToValue` trait. 92 /// - Using the standard `From` trait. 93 /// 94 /// ## Using the `Value::capture_*` methods 95 /// 96 /// `Value` offers a few constructor methods that capture values of different kinds. 97 /// These methods require a `T: 'static` to support downcasting. 98 /// 99 /// ``` 100 /// use log::kv::Value; 101 /// 102 /// let value = Value::capture_debug(&42i32); 103 /// 104 /// assert_eq!(Some(42), value.to_i64()); 105 /// ``` 106 /// 107 /// ## Using the `Value::from_*` methods 108 /// 109 /// `Value` offers a few constructor methods that capture values of different kinds. 110 /// These methods don't require `T: 'static`, but can't support downcasting. 111 /// 112 /// ``` 113 /// use log::kv::Value; 114 /// 115 /// let value = Value::from_debug(&42i32); 116 /// 117 /// assert_eq!(None, value.to_i64()); 118 /// ``` 119 /// 120 /// ## Using the `ToValue` trait 121 /// 122 /// The `ToValue` trait can be used to capture values generically. 123 /// It's the bound used by `Source`. 124 /// 125 /// ``` 126 /// # use log::kv::ToValue; 127 /// let value = 42i32.to_value(); 128 /// 129 /// assert_eq!(Some(42), value.to_i64()); 130 /// ``` 131 /// 132 /// ``` 133 /// # use std::fmt::Debug; 134 /// use log::kv::ToValue; 135 /// 136 /// let value = (&42i32 as &dyn Debug).to_value(); 137 /// 138 /// assert_eq!(None, value.to_i64()); 139 /// ``` 140 /// 141 /// ## Using the standard `From` trait 142 /// 143 /// Standard types that implement `ToValue` also implement `From`. 144 /// 145 /// ``` 146 /// use log::kv::Value; 147 /// 148 /// let value = Value::from(42i32); 149 /// 150 /// assert_eq!(Some(42), value.to_i64()); 151 /// ``` 152 pub struct Value<'v> { 153 inner: ValueBag<'v>, 154 } 155 156 impl<'v> Value<'v> { 157 /// Get a value from a type implementing `ToValue`. from_any<T>(value: &'v T) -> Self where T: ToValue,158 pub fn from_any<T>(value: &'v T) -> Self 159 where 160 T: ToValue, 161 { 162 value.to_value() 163 } 164 165 /// Get a value from a type implementing `std::fmt::Debug`. capture_debug<T>(value: &'v T) -> Self where T: fmt::Debug + 'static,166 pub fn capture_debug<T>(value: &'v T) -> Self 167 where 168 T: fmt::Debug + 'static, 169 { 170 Value { 171 inner: ValueBag::capture_debug(value), 172 } 173 } 174 175 /// Get a value from a type implementing `std::fmt::Display`. capture_display<T>(value: &'v T) -> Self where T: fmt::Display + 'static,176 pub fn capture_display<T>(value: &'v T) -> Self 177 where 178 T: fmt::Display + 'static, 179 { 180 Value { 181 inner: ValueBag::capture_display(value), 182 } 183 } 184 185 /// Get a value from an error. 186 #[cfg(feature = "kv_unstable_std")] capture_error<T>(err: &'v T) -> Self where T: std::error::Error + 'static,187 pub fn capture_error<T>(err: &'v T) -> Self 188 where 189 T: std::error::Error + 'static, 190 { 191 Value { 192 inner: ValueBag::capture_error(err), 193 } 194 } 195 196 #[cfg(feature = "kv_unstable_serde")] 197 /// Get a value from a type implementing `serde::Serialize`. capture_serde<T>(value: &'v T) -> Self where T: self::serde::Serialize + 'static,198 pub fn capture_serde<T>(value: &'v T) -> Self 199 where 200 T: self::serde::Serialize + 'static, 201 { 202 Value { 203 inner: ValueBag::capture_serde1(value), 204 } 205 } 206 207 /// Get a value from a type implementing `sval::value::Value`. 208 #[cfg(feature = "kv_unstable_sval")] capture_sval<T>(value: &'v T) -> Self where T: self::sval::value::Value + 'static,209 pub fn capture_sval<T>(value: &'v T) -> Self 210 where 211 T: self::sval::value::Value + 'static, 212 { 213 Value { 214 inner: ValueBag::capture_sval1(value), 215 } 216 } 217 218 /// Get a value from a type implementing `std::fmt::Debug`. from_debug<T>(value: &'v T) -> Self where T: fmt::Debug,219 pub fn from_debug<T>(value: &'v T) -> Self 220 where 221 T: fmt::Debug, 222 { 223 Value { 224 inner: ValueBag::from_debug(value), 225 } 226 } 227 228 /// Get a value from a type implementing `std::fmt::Display`. from_display<T>(value: &'v T) -> Self where T: fmt::Display,229 pub fn from_display<T>(value: &'v T) -> Self 230 where 231 T: fmt::Display, 232 { 233 Value { 234 inner: ValueBag::from_display(value), 235 } 236 } 237 238 /// Get a value from a type implementing `serde::Serialize`. 239 #[cfg(feature = "kv_unstable_serde")] from_serde<T>(value: &'v T) -> Self where T: self::serde::Serialize,240 pub fn from_serde<T>(value: &'v T) -> Self 241 where 242 T: self::serde::Serialize, 243 { 244 Value { 245 inner: ValueBag::from_serde1(value), 246 } 247 } 248 249 /// Get a value from a type implementing `sval::value::Value`. 250 #[cfg(feature = "kv_unstable_sval")] from_sval<T>(value: &'v T) -> Self where T: self::sval::value::Value,251 pub fn from_sval<T>(value: &'v T) -> Self 252 where 253 T: self::sval::value::Value, 254 { 255 Value { 256 inner: ValueBag::from_sval1(value), 257 } 258 } 259 260 /// Get a value from a dynamic `std::fmt::Debug`. from_dyn_debug(value: &'v dyn fmt::Debug) -> Self261 pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self { 262 Value { 263 inner: ValueBag::from_dyn_debug(value), 264 } 265 } 266 267 /// Get a value from a dynamic `std::fmt::Display`. from_dyn_display(value: &'v dyn fmt::Display) -> Self268 pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self { 269 Value { 270 inner: ValueBag::from_dyn_display(value), 271 } 272 } 273 274 /// Get a value from a dynamic error. 275 #[cfg(feature = "kv_unstable_std")] from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self276 pub fn from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self { 277 Value { 278 inner: ValueBag::from_dyn_error(err), 279 } 280 } 281 282 /// Get a value from a type implementing `sval::value::Value`. 283 #[cfg(feature = "kv_unstable_sval")] from_dyn_sval(value: &'v dyn self::sval::value::Value) -> Self284 pub fn from_dyn_sval(value: &'v dyn self::sval::value::Value) -> Self { 285 Value { 286 inner: ValueBag::from_dyn_sval1(value), 287 } 288 } 289 290 /// Get a value from an internal primitive. from_value_bag<T>(value: T) -> Self where T: Into<ValueBag<'v>>,291 fn from_value_bag<T>(value: T) -> Self 292 where 293 T: Into<ValueBag<'v>>, 294 { 295 Value { 296 inner: value.into(), 297 } 298 } 299 300 /// Check whether this value can be downcast to `T`. is<T: 'static>(&self) -> bool301 pub fn is<T: 'static>(&self) -> bool { 302 self.inner.is::<T>() 303 } 304 305 /// Try downcast this value to `T`. downcast_ref<T: 'static>(&self) -> Option<&T>306 pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { 307 self.inner.downcast_ref::<T>() 308 } 309 310 /// Inspect this value using a simple visitor. visit(&self, visitor: impl Visit<'v>) -> Result<(), Error>311 pub fn visit(&self, visitor: impl Visit<'v>) -> Result<(), Error> { 312 struct Visitor<V>(V); 313 314 impl<'v, V> value_bag::visit::Visit<'v> for Visitor<V> 315 where 316 V: Visit<'v>, 317 { 318 fn visit_any(&mut self, value: ValueBag) -> Result<(), value_bag::Error> { 319 self.0 320 .visit_any(Value { inner: value }) 321 .map_err(Error::into_value) 322 } 323 324 fn visit_u64(&mut self, value: u64) -> Result<(), value_bag::Error> { 325 self.0.visit_u64(value).map_err(Error::into_value) 326 } 327 328 fn visit_i64(&mut self, value: i64) -> Result<(), value_bag::Error> { 329 self.0.visit_i64(value).map_err(Error::into_value) 330 } 331 332 fn visit_u128(&mut self, value: u128) -> Result<(), value_bag::Error> { 333 self.0.visit_u128(value).map_err(Error::into_value) 334 } 335 336 fn visit_i128(&mut self, value: i128) -> Result<(), value_bag::Error> { 337 self.0.visit_i128(value).map_err(Error::into_value) 338 } 339 340 fn visit_f64(&mut self, value: f64) -> Result<(), value_bag::Error> { 341 self.0.visit_f64(value).map_err(Error::into_value) 342 } 343 344 fn visit_bool(&mut self, value: bool) -> Result<(), value_bag::Error> { 345 self.0.visit_bool(value).map_err(Error::into_value) 346 } 347 348 fn visit_str(&mut self, value: &str) -> Result<(), value_bag::Error> { 349 self.0.visit_str(value).map_err(Error::into_value) 350 } 351 352 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), value_bag::Error> { 353 self.0.visit_borrowed_str(value).map_err(Error::into_value) 354 } 355 356 fn visit_char(&mut self, value: char) -> Result<(), value_bag::Error> { 357 self.0.visit_char(value).map_err(Error::into_value) 358 } 359 360 #[cfg(feature = "kv_unstable_std")] 361 fn visit_error( 362 &mut self, 363 err: &(dyn std::error::Error + 'static), 364 ) -> Result<(), value_bag::Error> { 365 self.0.visit_error(err).map_err(Error::into_value) 366 } 367 368 #[cfg(feature = "kv_unstable_std")] 369 fn visit_borrowed_error( 370 &mut self, 371 err: &'v (dyn std::error::Error + 'static), 372 ) -> Result<(), value_bag::Error> { 373 self.0.visit_borrowed_error(err).map_err(Error::into_value) 374 } 375 } 376 377 self.inner 378 .visit(&mut Visitor(visitor)) 379 .map_err(Error::from_value) 380 } 381 } 382 383 impl<'v> fmt::Debug for Value<'v> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result384 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 385 fmt::Debug::fmt(&self.inner, f) 386 } 387 } 388 389 impl<'v> fmt::Display for Value<'v> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result390 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 391 fmt::Display::fmt(&self.inner, f) 392 } 393 } 394 395 impl ToValue for dyn fmt::Debug { to_value(&self) -> Value396 fn to_value(&self) -> Value { 397 Value::from_dyn_debug(self) 398 } 399 } 400 401 impl ToValue for dyn fmt::Display { to_value(&self) -> Value402 fn to_value(&self) -> Value { 403 Value::from_dyn_display(self) 404 } 405 } 406 407 #[cfg(feature = "kv_unstable_std")] 408 impl ToValue for dyn std::error::Error + 'static { to_value(&self) -> Value409 fn to_value(&self) -> Value { 410 Value::from_dyn_error(self) 411 } 412 } 413 414 #[cfg(feature = "kv_unstable_serde")] 415 impl<'v> self::serde::Serialize for Value<'v> { serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> where S: self::serde::Serializer,416 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> 417 where 418 S: self::serde::Serializer, 419 { 420 self.inner.serialize(s) 421 } 422 } 423 424 #[cfg(feature = "kv_unstable_sval")] 425 impl<'v> self::sval::value::Value for Value<'v> { stream(&self, stream: &mut self::sval::value::Stream) -> self::sval::value::Result426 fn stream(&self, stream: &mut self::sval::value::Stream) -> self::sval::value::Result { 427 self::sval::value::Value::stream(&self.inner, stream) 428 } 429 } 430 431 #[cfg(feature = "kv_unstable_sval")] 432 impl ToValue for dyn self::sval::value::Value { to_value(&self) -> Value433 fn to_value(&self) -> Value { 434 Value::from_dyn_sval(self) 435 } 436 } 437 438 impl ToValue for str { to_value(&self) -> Value439 fn to_value(&self) -> Value { 440 Value::from(self) 441 } 442 } 443 444 impl ToValue for u128 { to_value(&self) -> Value445 fn to_value(&self) -> Value { 446 Value::from(self) 447 } 448 } 449 450 impl ToValue for i128 { to_value(&self) -> Value451 fn to_value(&self) -> Value { 452 Value::from(self) 453 } 454 } 455 456 impl ToValue for std::num::NonZeroU128 { to_value(&self) -> Value457 fn to_value(&self) -> Value { 458 Value::from(self) 459 } 460 } 461 462 impl ToValue for std::num::NonZeroI128 { to_value(&self) -> Value463 fn to_value(&self) -> Value { 464 Value::from(self) 465 } 466 } 467 468 impl<'v> From<&'v str> for Value<'v> { from(value: &'v str) -> Self469 fn from(value: &'v str) -> Self { 470 Value::from_value_bag(value) 471 } 472 } 473 474 impl<'v> From<&'v u128> for Value<'v> { from(value: &'v u128) -> Self475 fn from(value: &'v u128) -> Self { 476 Value::from_value_bag(value) 477 } 478 } 479 480 impl<'v> From<&'v i128> for Value<'v> { from(value: &'v i128) -> Self481 fn from(value: &'v i128) -> Self { 482 Value::from_value_bag(value) 483 } 484 } 485 486 impl<'v> From<&'v std::num::NonZeroU128> for Value<'v> { from(v: &'v std::num::NonZeroU128) -> Value<'v>487 fn from(v: &'v std::num::NonZeroU128) -> Value<'v> { 488 // SAFETY: `NonZeroU128` and `u128` have the same ABI 489 Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroU128, &u128>(v) }) 490 } 491 } 492 493 impl<'v> From<&'v std::num::NonZeroI128> for Value<'v> { from(v: &'v std::num::NonZeroI128) -> Value<'v>494 fn from(v: &'v std::num::NonZeroI128) -> Value<'v> { 495 // SAFETY: `NonZeroI128` and `i128` have the same ABI 496 Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroI128, &i128>(v) }) 497 } 498 } 499 500 impl ToValue for () { to_value(&self) -> Value501 fn to_value(&self) -> Value { 502 Value::from_value_bag(()) 503 } 504 } 505 506 impl<T> ToValue for Option<T> 507 where 508 T: ToValue, 509 { to_value(&self) -> Value510 fn to_value(&self) -> Value { 511 match *self { 512 Some(ref value) => value.to_value(), 513 None => Value::from_value_bag(()), 514 } 515 } 516 } 517 518 macro_rules! impl_to_value_primitive { 519 ($($into_ty:ty,)*) => { 520 $( 521 impl ToValue for $into_ty { 522 fn to_value(&self) -> Value { 523 Value::from(*self) 524 } 525 } 526 527 impl<'v> From<$into_ty> for Value<'v> { 528 fn from(value: $into_ty) -> Self { 529 Value::from_value_bag(value) 530 } 531 } 532 )* 533 }; 534 } 535 536 macro_rules! impl_to_value_nonzero_primitive { 537 ($($into_ty:ident,)*) => { 538 $( 539 impl ToValue for std::num::$into_ty { 540 fn to_value(&self) -> Value { 541 Value::from(self.get()) 542 } 543 } 544 545 impl<'v> From<std::num::$into_ty> for Value<'v> { 546 fn from(value: std::num::$into_ty) -> Self { 547 Value::from(value.get()) 548 } 549 } 550 )* 551 }; 552 } 553 554 macro_rules! impl_value_to_primitive { 555 ($(#[doc = $doc:tt] $into_name:ident -> $into_ty:ty,)*) => { 556 impl<'v> Value<'v> { 557 $( 558 #[doc = $doc] 559 pub fn $into_name(&self) -> Option<$into_ty> { 560 self.inner.$into_name() 561 } 562 )* 563 } 564 } 565 } 566 567 impl_to_value_primitive![usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64, char, bool,]; 568 569 #[rustfmt::skip] 570 impl_to_value_nonzero_primitive![ 571 NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, 572 NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, 573 ]; 574 575 impl_value_to_primitive![ 576 #[doc = "Try convert this value into a `u64`."] 577 to_u64 -> u64, 578 #[doc = "Try convert this value into a `i64`."] 579 to_i64 -> i64, 580 #[doc = "Try convert this value into a `u128`."] 581 to_u128 -> u128, 582 #[doc = "Try convert this value into a `i128`."] 583 to_i128 -> i128, 584 #[doc = "Try convert this value into a `f64`."] 585 to_f64 -> f64, 586 #[doc = "Try convert this value into a `char`."] 587 to_char -> char, 588 #[doc = "Try convert this value into a `bool`."] 589 to_bool -> bool, 590 ]; 591 592 impl<'v> Value<'v> { 593 /// Try convert this value into an error. 594 #[cfg(feature = "kv_unstable_std")] to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)>595 pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> { 596 self.inner.to_borrowed_error() 597 } 598 599 /// Try convert this value into a borrowed string. to_borrowed_str(&self) -> Option<&str>600 pub fn to_borrowed_str(&self) -> Option<&str> { 601 self.inner.to_borrowed_str() 602 } 603 } 604 605 #[cfg(feature = "kv_unstable_std")] 606 mod std_support { 607 use super::*; 608 609 use std::borrow::Cow; 610 611 impl<T> ToValue for Box<T> 612 where 613 T: ToValue + ?Sized, 614 { to_value(&self) -> Value615 fn to_value(&self) -> Value { 616 (**self).to_value() 617 } 618 } 619 620 impl ToValue for String { to_value(&self) -> Value621 fn to_value(&self) -> Value { 622 Value::from(&**self) 623 } 624 } 625 626 impl<'v> ToValue for Cow<'v, str> { to_value(&self) -> Value627 fn to_value(&self) -> Value { 628 Value::from(&**self) 629 } 630 } 631 632 impl<'v> Value<'v> { 633 /// Try convert this value into a string. to_str(&self) -> Option<Cow<str>>634 pub fn to_str(&self) -> Option<Cow<str>> { 635 self.inner.to_str() 636 } 637 } 638 639 impl<'v> From<&'v String> for Value<'v> { from(v: &'v String) -> Self640 fn from(v: &'v String) -> Self { 641 Value::from(&**v) 642 } 643 } 644 } 645 646 /// A visitor for a `Value`. 647 pub trait Visit<'v> { 648 /// Visit a `Value`. 649 /// 650 /// This is the only required method on `Visit` and acts as a fallback for any 651 /// more specific methods that aren't overridden. 652 /// The `Value` may be formatted using its `fmt::Debug` or `fmt::Display` implementation, 653 /// or serialized using its `sval::Value` or `serde::Serialize` implementation. visit_any(&mut self, value: Value) -> Result<(), Error>654 fn visit_any(&mut self, value: Value) -> Result<(), Error>; 655 656 /// Visit an unsigned integer. visit_u64(&mut self, value: u64) -> Result<(), Error>657 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 658 self.visit_any(value.into()) 659 } 660 661 /// Visit a signed integer. visit_i64(&mut self, value: i64) -> Result<(), Error>662 fn visit_i64(&mut self, value: i64) -> Result<(), Error> { 663 self.visit_any(value.into()) 664 } 665 666 /// Visit a big unsigned integer. visit_u128(&mut self, value: u128) -> Result<(), Error>667 fn visit_u128(&mut self, value: u128) -> Result<(), Error> { 668 self.visit_any((&value).into()) 669 } 670 671 /// Visit a big signed integer. visit_i128(&mut self, value: i128) -> Result<(), Error>672 fn visit_i128(&mut self, value: i128) -> Result<(), Error> { 673 self.visit_any((&value).into()) 674 } 675 676 /// Visit a floating point. visit_f64(&mut self, value: f64) -> Result<(), Error>677 fn visit_f64(&mut self, value: f64) -> Result<(), Error> { 678 self.visit_any(value.into()) 679 } 680 681 /// Visit a boolean. visit_bool(&mut self, value: bool) -> Result<(), Error>682 fn visit_bool(&mut self, value: bool) -> Result<(), Error> { 683 self.visit_any(value.into()) 684 } 685 686 /// Visit a string. visit_str(&mut self, value: &str) -> Result<(), Error>687 fn visit_str(&mut self, value: &str) -> Result<(), Error> { 688 self.visit_any(value.into()) 689 } 690 691 /// Visit a string. visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error>692 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 693 self.visit_str(value) 694 } 695 696 /// Visit a Unicode character. visit_char(&mut self, value: char) -> Result<(), Error>697 fn visit_char(&mut self, value: char) -> Result<(), Error> { 698 let mut b = [0; 4]; 699 self.visit_str(&*value.encode_utf8(&mut b)) 700 } 701 702 /// Visit an error. 703 #[cfg(feature = "kv_unstable_std")] visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error>704 fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> { 705 self.visit_any(Value::from_dyn_error(err)) 706 } 707 708 /// Visit an error. 709 #[cfg(feature = "kv_unstable_std")] visit_borrowed_error( &mut self, err: &'v (dyn std::error::Error + 'static), ) -> Result<(), Error>710 fn visit_borrowed_error( 711 &mut self, 712 err: &'v (dyn std::error::Error + 'static), 713 ) -> Result<(), Error> { 714 self.visit_any(Value::from_dyn_error(err)) 715 } 716 } 717 718 impl<'a, 'v, T: ?Sized> Visit<'v> for &'a mut T 719 where 720 T: Visit<'v>, 721 { visit_any(&mut self, value: Value) -> Result<(), Error>722 fn visit_any(&mut self, value: Value) -> Result<(), Error> { 723 (**self).visit_any(value) 724 } 725 visit_u64(&mut self, value: u64) -> Result<(), Error>726 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 727 (**self).visit_u64(value) 728 } 729 visit_i64(&mut self, value: i64) -> Result<(), Error>730 fn visit_i64(&mut self, value: i64) -> Result<(), Error> { 731 (**self).visit_i64(value) 732 } 733 visit_u128(&mut self, value: u128) -> Result<(), Error>734 fn visit_u128(&mut self, value: u128) -> Result<(), Error> { 735 (**self).visit_u128(value) 736 } 737 visit_i128(&mut self, value: i128) -> Result<(), Error>738 fn visit_i128(&mut self, value: i128) -> Result<(), Error> { 739 (**self).visit_i128(value) 740 } 741 visit_f64(&mut self, value: f64) -> Result<(), Error>742 fn visit_f64(&mut self, value: f64) -> Result<(), Error> { 743 (**self).visit_f64(value) 744 } 745 visit_bool(&mut self, value: bool) -> Result<(), Error>746 fn visit_bool(&mut self, value: bool) -> Result<(), Error> { 747 (**self).visit_bool(value) 748 } 749 visit_str(&mut self, value: &str) -> Result<(), Error>750 fn visit_str(&mut self, value: &str) -> Result<(), Error> { 751 (**self).visit_str(value) 752 } 753 visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error>754 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 755 (**self).visit_borrowed_str(value) 756 } 757 visit_char(&mut self, value: char) -> Result<(), Error>758 fn visit_char(&mut self, value: char) -> Result<(), Error> { 759 (**self).visit_char(value) 760 } 761 762 #[cfg(feature = "kv_unstable_std")] visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error>763 fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> { 764 (**self).visit_error(err) 765 } 766 767 #[cfg(feature = "kv_unstable_std")] visit_borrowed_error( &mut self, err: &'v (dyn std::error::Error + 'static), ) -> Result<(), Error>768 fn visit_borrowed_error( 769 &mut self, 770 err: &'v (dyn std::error::Error + 'static), 771 ) -> Result<(), Error> { 772 (**self).visit_borrowed_error(err) 773 } 774 } 775 776 #[cfg(test)] 777 pub(crate) mod tests { 778 use super::*; 779 780 pub(crate) use super::value_bag::test::Token; 781 782 impl<'v> Value<'v> { to_token(&self) -> Token783 pub(crate) fn to_token(&self) -> Token { 784 self.inner.to_token() 785 } 786 } 787 unsigned() -> impl Iterator<Item = Value<'static>>788 fn unsigned() -> impl Iterator<Item = Value<'static>> { 789 vec![ 790 Value::from(8u8), 791 Value::from(16u16), 792 Value::from(32u32), 793 Value::from(64u64), 794 Value::from(1usize), 795 Value::from(std::num::NonZeroU8::new(8).unwrap()), 796 Value::from(std::num::NonZeroU16::new(16).unwrap()), 797 Value::from(std::num::NonZeroU32::new(32).unwrap()), 798 Value::from(std::num::NonZeroU64::new(64).unwrap()), 799 Value::from(std::num::NonZeroUsize::new(1).unwrap()), 800 ] 801 .into_iter() 802 } 803 signed() -> impl Iterator<Item = Value<'static>>804 fn signed() -> impl Iterator<Item = Value<'static>> { 805 vec![ 806 Value::from(-8i8), 807 Value::from(-16i16), 808 Value::from(-32i32), 809 Value::from(-64i64), 810 Value::from(-1isize), 811 Value::from(std::num::NonZeroI8::new(-8).unwrap()), 812 Value::from(std::num::NonZeroI16::new(-16).unwrap()), 813 Value::from(std::num::NonZeroI32::new(-32).unwrap()), 814 Value::from(std::num::NonZeroI64::new(-64).unwrap()), 815 Value::from(std::num::NonZeroIsize::new(-1).unwrap()), 816 ] 817 .into_iter() 818 } 819 float() -> impl Iterator<Item = Value<'static>>820 fn float() -> impl Iterator<Item = Value<'static>> { 821 vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter() 822 } 823 bool() -> impl Iterator<Item = Value<'static>>824 fn bool() -> impl Iterator<Item = Value<'static>> { 825 vec![Value::from(true), Value::from(false)].into_iter() 826 } 827 str() -> impl Iterator<Item = Value<'static>>828 fn str() -> impl Iterator<Item = Value<'static>> { 829 vec![Value::from("a string"), Value::from("a loong string")].into_iter() 830 } 831 char() -> impl Iterator<Item = Value<'static>>832 fn char() -> impl Iterator<Item = Value<'static>> { 833 vec![Value::from('a'), Value::from('⛰')].into_iter() 834 } 835 836 #[test] test_capture_fmt()837 fn test_capture_fmt() { 838 assert_eq!(Some(42u64), Value::capture_display(&42).to_u64()); 839 assert_eq!(Some(42u64), Value::capture_debug(&42).to_u64()); 840 841 assert!(Value::from_display(&42).to_u64().is_none()); 842 assert!(Value::from_debug(&42).to_u64().is_none()); 843 } 844 845 #[cfg(feature = "kv_unstable_std")] 846 #[test] test_capture_error()847 fn test_capture_error() { 848 let err = std::io::Error::from(std::io::ErrorKind::Other); 849 850 assert!(Value::capture_error(&err).to_borrowed_error().is_some()); 851 assert!(Value::from_dyn_error(&err).to_borrowed_error().is_some()); 852 } 853 854 #[cfg(feature = "kv_unstable_serde")] 855 #[test] test_capture_serde()856 fn test_capture_serde() { 857 assert_eq!(Some(42u64), Value::capture_serde(&42).to_u64()); 858 859 assert_eq!(Some(42u64), Value::from_serde(&42).to_u64()); 860 } 861 862 #[cfg(feature = "kv_unstable_sval")] 863 #[test] test_capture_sval()864 fn test_capture_sval() { 865 assert_eq!(Some(42u64), Value::capture_sval(&42).to_u64()); 866 867 assert_eq!(Some(42u64), Value::from_sval(&42).to_u64()); 868 } 869 870 #[test] test_to_value_display()871 fn test_to_value_display() { 872 assert_eq!(42u64.to_value().to_string(), "42"); 873 assert_eq!(42i64.to_value().to_string(), "42"); 874 assert_eq!(42.01f64.to_value().to_string(), "42.01"); 875 assert_eq!(true.to_value().to_string(), "true"); 876 assert_eq!('a'.to_value().to_string(), "a"); 877 assert_eq!("a loong string".to_value().to_string(), "a loong string"); 878 assert_eq!(Some(true).to_value().to_string(), "true"); 879 assert_eq!(().to_value().to_string(), "None"); 880 assert_eq!(Option::None::<bool>.to_value().to_string(), "None"); 881 } 882 883 #[test] test_to_value_structured()884 fn test_to_value_structured() { 885 assert_eq!(42u64.to_value().to_token(), Token::U64(42)); 886 assert_eq!(42i64.to_value().to_token(), Token::I64(42)); 887 assert_eq!(42.01f64.to_value().to_token(), Token::F64(42.01)); 888 assert_eq!(true.to_value().to_token(), Token::Bool(true)); 889 assert_eq!('a'.to_value().to_token(), Token::Char('a')); 890 assert_eq!( 891 "a loong string".to_value().to_token(), 892 Token::Str("a loong string".into()) 893 ); 894 assert_eq!(Some(true).to_value().to_token(), Token::Bool(true)); 895 assert_eq!(().to_value().to_token(), Token::None); 896 assert_eq!(Option::None::<bool>.to_value().to_token(), Token::None); 897 } 898 899 #[test] test_to_number()900 fn test_to_number() { 901 for v in unsigned() { 902 assert!(v.to_u64().is_some()); 903 assert!(v.to_i64().is_some()); 904 } 905 906 for v in signed() { 907 assert!(v.to_i64().is_some()); 908 } 909 910 for v in unsigned().chain(signed()).chain(float()) { 911 assert!(v.to_f64().is_some()); 912 } 913 914 for v in bool().chain(str()).chain(char()) { 915 assert!(v.to_u64().is_none()); 916 assert!(v.to_i64().is_none()); 917 assert!(v.to_f64().is_none()); 918 } 919 } 920 921 #[test] test_to_str()922 fn test_to_str() { 923 for v in str() { 924 assert!(v.to_borrowed_str().is_some()); 925 926 #[cfg(feature = "kv_unstable_std")] 927 assert!(v.to_str().is_some()); 928 } 929 930 let short_lived = String::from("short lived"); 931 let v = Value::from(&*short_lived); 932 933 assert!(v.to_borrowed_str().is_some()); 934 935 #[cfg(feature = "kv_unstable_std")] 936 assert!(v.to_str().is_some()); 937 938 for v in unsigned().chain(signed()).chain(float()).chain(bool()) { 939 assert!(v.to_borrowed_str().is_none()); 940 941 #[cfg(feature = "kv_unstable_std")] 942 assert!(v.to_str().is_none()); 943 } 944 } 945 946 #[test] test_to_bool()947 fn test_to_bool() { 948 for v in bool() { 949 assert!(v.to_bool().is_some()); 950 } 951 952 for v in unsigned() 953 .chain(signed()) 954 .chain(float()) 955 .chain(str()) 956 .chain(char()) 957 { 958 assert!(v.to_bool().is_none()); 959 } 960 } 961 962 #[test] test_to_char()963 fn test_to_char() { 964 for v in char() { 965 assert!(v.to_char().is_some()); 966 } 967 968 for v in unsigned() 969 .chain(signed()) 970 .chain(float()) 971 .chain(str()) 972 .chain(bool()) 973 { 974 assert!(v.to_char().is_none()); 975 } 976 } 977 978 #[test] test_downcast_ref()979 fn test_downcast_ref() { 980 #[derive(Debug)] 981 struct Foo(u64); 982 983 let v = Value::capture_debug(&Foo(42)); 984 985 assert!(v.is::<Foo>()); 986 assert_eq!(42u64, v.downcast_ref::<Foo>().expect("invalid downcast").0); 987 } 988 989 #[test] test_visit_integer()990 fn test_visit_integer() { 991 struct Extract(Option<u64>); 992 993 impl<'v> Visit<'v> for Extract { 994 fn visit_any(&mut self, value: Value) -> Result<(), Error> { 995 unimplemented!("unexpected value: {:?}", value) 996 } 997 998 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 999 self.0 = Some(value); 1000 1001 Ok(()) 1002 } 1003 } 1004 1005 let mut extract = Extract(None); 1006 Value::from(42u64).visit(&mut extract).unwrap(); 1007 1008 assert_eq!(Some(42), extract.0); 1009 } 1010 1011 #[test] test_visit_borrowed_str()1012 fn test_visit_borrowed_str() { 1013 struct Extract<'v>(Option<&'v str>); 1014 1015 impl<'v> Visit<'v> for Extract<'v> { 1016 fn visit_any(&mut self, value: Value) -> Result<(), Error> { 1017 unimplemented!("unexpected value: {:?}", value) 1018 } 1019 1020 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 1021 self.0 = Some(value); 1022 1023 Ok(()) 1024 } 1025 } 1026 1027 let mut extract = Extract(None); 1028 1029 let short_lived = String::from("A short-lived string"); 1030 Value::from(&*short_lived).visit(&mut extract).unwrap(); 1031 1032 assert_eq!(Some("A short-lived string"), extract.0); 1033 } 1034 } 1035