1 //! Structured values. 2 //! 3 //! This module defines the [`Value`] type and supporting APIs for 4 //! capturing and serializing them. 5 6 use std::fmt; 7 8 pub use crate::kv::Error; 9 10 /// A type that can be converted into a [`Value`](struct.Value.html). 11 pub trait ToValue { 12 /// Perform the conversion. to_value(&self) -> Value13 fn to_value(&self) -> Value; 14 } 15 16 impl<'a, T> ToValue for &'a T 17 where 18 T: ToValue + ?Sized, 19 { to_value(&self) -> Value20 fn to_value(&self) -> Value { 21 (**self).to_value() 22 } 23 } 24 25 impl<'v> ToValue for Value<'v> { to_value(&self) -> Value26 fn to_value(&self) -> Value { 27 Value { 28 inner: self.inner.clone(), 29 } 30 } 31 } 32 33 /// A value in a key-value. 34 /// 35 /// Values are an anonymous bag containing some structured datum. 36 /// 37 /// # Capturing values 38 /// 39 /// There are a few ways to capture a value: 40 /// 41 /// - Using the `Value::from_*` methods. 42 /// - Using the `ToValue` trait. 43 /// - Using the standard `From` trait. 44 /// 45 /// ## Using the `Value::from_*` methods 46 /// 47 /// `Value` offers a few constructor methods that capture values of different kinds. 48 /// 49 /// ``` 50 /// use log::kv::Value; 51 /// 52 /// let value = Value::from_debug(&42i32); 53 /// 54 /// assert_eq!(None, value.to_i64()); 55 /// ``` 56 /// 57 /// ## Using the `ToValue` trait 58 /// 59 /// The `ToValue` trait can be used to capture values generically. 60 /// It's the bound used by `Source`. 61 /// 62 /// ``` 63 /// # use log::kv::ToValue; 64 /// let value = 42i32.to_value(); 65 /// 66 /// assert_eq!(Some(42), value.to_i64()); 67 /// ``` 68 /// 69 /// ## Using the standard `From` trait 70 /// 71 /// Standard types that implement `ToValue` also implement `From`. 72 /// 73 /// ``` 74 /// use log::kv::Value; 75 /// 76 /// let value = Value::from(42i32); 77 /// 78 /// assert_eq!(Some(42), value.to_i64()); 79 /// ``` 80 /// 81 /// # Data model 82 /// 83 /// Values can hold one of a number of types: 84 /// 85 /// - **Null:** The absence of any other meaningful value. Note that 86 /// `Some(Value::null())` is not the same as `None`. The former is 87 /// `null` while the latter is `undefined`. This is important to be 88 /// able to tell the difference between a key-value that was logged, 89 /// but its value was empty (`Some(Value::null())`) and a key-value 90 /// that was never logged at all (`None`). 91 /// - **Strings:** `str`, `char`. 92 /// - **Booleans:** `bool`. 93 /// - **Integers:** `u8`-`u128`, `i8`-`i128`, `NonZero*`. 94 /// - **Floating point numbers:** `f32`-`f64`. 95 /// - **Errors:** `dyn (Error + 'static)`. 96 /// - **`serde`:** Any type in `serde`'s data model. 97 /// - **`sval`:** Any type in `sval`'s data model. 98 /// 99 /// # Serialization 100 /// 101 /// Values provide a number of ways to be serialized. 102 /// 103 /// For basic types the [`Value::visit`] method can be used to extract the 104 /// underlying typed value. However this is limited in the amount of types 105 /// supported (see the [`VisitValue`] trait methods). 106 /// 107 /// For more complex types one of the following traits can be used: 108 /// * `sval::Value`, requires the `kv_sval` feature. 109 /// * `serde::Serialize`, requires the `kv_serde` feature. 110 /// 111 /// You don't need a visitor to serialize values through `serde` or `sval`. 112 /// 113 /// A value can always be serialized using any supported framework, regardless 114 /// of how it was captured. If, for example, a value was captured using its 115 /// `Display` implementation, it will serialize through `serde` as a string. If it was 116 /// captured as a struct using `serde`, it will also serialize as a struct 117 /// through `sval`, or can be formatted using a `Debug`-compatible representation. 118 pub struct Value<'v> { 119 inner: inner::Inner<'v>, 120 } 121 122 impl<'v> Value<'v> { 123 /// Get a value from a type implementing `ToValue`. from_any<T>(value: &'v T) -> Self where T: ToValue,124 pub fn from_any<T>(value: &'v T) -> Self 125 where 126 T: ToValue, 127 { 128 value.to_value() 129 } 130 131 /// Get a value from a type implementing `std::fmt::Debug`. from_debug<T>(value: &'v T) -> Self where T: fmt::Debug,132 pub fn from_debug<T>(value: &'v T) -> Self 133 where 134 T: fmt::Debug, 135 { 136 Value { 137 inner: inner::Inner::from_debug(value), 138 } 139 } 140 141 /// Get a value from a type implementing `std::fmt::Display`. from_display<T>(value: &'v T) -> Self where T: fmt::Display,142 pub fn from_display<T>(value: &'v T) -> Self 143 where 144 T: fmt::Display, 145 { 146 Value { 147 inner: inner::Inner::from_display(value), 148 } 149 } 150 151 /// Get a value from a type implementing `serde::Serialize`. 152 #[cfg(feature = "kv_serde")] from_serde<T>(value: &'v T) -> Self where T: serde::Serialize,153 pub fn from_serde<T>(value: &'v T) -> Self 154 where 155 T: serde::Serialize, 156 { 157 Value { 158 inner: inner::Inner::from_serde1(value), 159 } 160 } 161 162 /// Get a value from a type implementing `sval::Value`. 163 #[cfg(feature = "kv_sval")] from_sval<T>(value: &'v T) -> Self where T: sval::Value,164 pub fn from_sval<T>(value: &'v T) -> Self 165 where 166 T: sval::Value, 167 { 168 Value { 169 inner: inner::Inner::from_sval2(value), 170 } 171 } 172 173 /// Get a value from a dynamic `std::fmt::Debug`. from_dyn_debug(value: &'v dyn fmt::Debug) -> Self174 pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self { 175 Value { 176 inner: inner::Inner::from_dyn_debug(value), 177 } 178 } 179 180 /// Get a value from a dynamic `std::fmt::Display`. from_dyn_display(value: &'v dyn fmt::Display) -> Self181 pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self { 182 Value { 183 inner: inner::Inner::from_dyn_display(value), 184 } 185 } 186 187 /// Get a value from a dynamic error. 188 #[cfg(feature = "kv_std")] from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self189 pub fn from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self { 190 Value { 191 inner: inner::Inner::from_dyn_error(err), 192 } 193 } 194 195 /// Get a `null` value. null() -> Self196 pub fn null() -> Self { 197 Value { 198 inner: inner::Inner::empty(), 199 } 200 } 201 202 /// Get a value from an internal primitive. from_inner<T>(value: T) -> Self where T: Into<inner::Inner<'v>>,203 fn from_inner<T>(value: T) -> Self 204 where 205 T: Into<inner::Inner<'v>>, 206 { 207 Value { 208 inner: value.into(), 209 } 210 } 211 212 /// Inspect this value using a simple visitor. 213 /// 214 /// When the `kv_serde` or `kv_sval` features are enabled, you can also 215 /// serialize a value using its `Serialize` or `Value` implementation. visit(&self, visitor: impl VisitValue<'v>) -> Result<(), Error>216 pub fn visit(&self, visitor: impl VisitValue<'v>) -> Result<(), Error> { 217 inner::visit(&self.inner, visitor) 218 } 219 } 220 221 impl<'v> fmt::Debug for Value<'v> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result222 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 223 fmt::Debug::fmt(&self.inner, f) 224 } 225 } 226 227 impl<'v> fmt::Display for Value<'v> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result228 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 229 fmt::Display::fmt(&self.inner, f) 230 } 231 } 232 233 #[cfg(feature = "kv_serde")] 234 impl<'v> serde::Serialize for Value<'v> { serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> where S: serde::Serializer,235 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error> 236 where 237 S: serde::Serializer, 238 { 239 self.inner.serialize(s) 240 } 241 } 242 243 #[cfg(feature = "kv_sval")] 244 impl<'v> sval::Value for Value<'v> { stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result245 fn stream<'sval, S: sval::Stream<'sval> + ?Sized>(&'sval self, stream: &mut S) -> sval::Result { 246 sval::Value::stream(&self.inner, stream) 247 } 248 } 249 250 #[cfg(feature = "kv_sval")] 251 impl<'v> sval_ref::ValueRef<'v> for Value<'v> { stream_ref<S: sval::Stream<'v> + ?Sized>(&self, stream: &mut S) -> sval::Result252 fn stream_ref<S: sval::Stream<'v> + ?Sized>(&self, stream: &mut S) -> sval::Result { 253 sval_ref::ValueRef::stream_ref(&self.inner, stream) 254 } 255 } 256 257 impl ToValue for str { to_value(&self) -> Value258 fn to_value(&self) -> Value { 259 Value::from(self) 260 } 261 } 262 263 impl<'v> From<&'v str> for Value<'v> { from(value: &'v str) -> Self264 fn from(value: &'v str) -> Self { 265 Value::from_inner(value) 266 } 267 } 268 269 impl ToValue for () { to_value(&self) -> Value270 fn to_value(&self) -> Value { 271 Value::from_inner(()) 272 } 273 } 274 275 impl<T> ToValue for Option<T> 276 where 277 T: ToValue, 278 { to_value(&self) -> Value279 fn to_value(&self) -> Value { 280 match *self { 281 Some(ref value) => value.to_value(), 282 None => Value::from_inner(()), 283 } 284 } 285 } 286 287 macro_rules! impl_to_value_primitive { 288 ($($into_ty:ty,)*) => { 289 $( 290 impl ToValue for $into_ty { 291 fn to_value(&self) -> Value { 292 Value::from(*self) 293 } 294 } 295 296 impl<'v> From<$into_ty> for Value<'v> { 297 fn from(value: $into_ty) -> Self { 298 Value::from_inner(value) 299 } 300 } 301 302 impl<'v> From<&'v $into_ty> for Value<'v> { 303 fn from(value: &'v $into_ty) -> Self { 304 Value::from_inner(*value) 305 } 306 } 307 )* 308 }; 309 } 310 311 macro_rules! impl_to_value_nonzero_primitive { 312 ($($into_ty:ident,)*) => { 313 $( 314 impl ToValue for std::num::$into_ty { 315 fn to_value(&self) -> Value { 316 Value::from(self.get()) 317 } 318 } 319 320 impl<'v> From<std::num::$into_ty> for Value<'v> { 321 fn from(value: std::num::$into_ty) -> Self { 322 Value::from(value.get()) 323 } 324 } 325 326 impl<'v> From<&'v std::num::$into_ty> for Value<'v> { 327 fn from(value: &'v std::num::$into_ty) -> Self { 328 Value::from(value.get()) 329 } 330 } 331 )* 332 }; 333 } 334 335 macro_rules! impl_value_to_primitive { 336 ($(#[doc = $doc:tt] $into_name:ident -> $into_ty:ty,)*) => { 337 impl<'v> Value<'v> { 338 $( 339 #[doc = $doc] 340 pub fn $into_name(&self) -> Option<$into_ty> { 341 self.inner.$into_name() 342 } 343 )* 344 } 345 } 346 } 347 348 impl_to_value_primitive![ 349 usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64, char, bool, 350 ]; 351 352 #[rustfmt::skip] 353 impl_to_value_nonzero_primitive![ 354 NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, 355 NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, 356 ]; 357 358 impl_value_to_primitive![ 359 #[doc = "Try convert this value into a `u64`."] 360 to_u64 -> u64, 361 #[doc = "Try convert this value into a `i64`."] 362 to_i64 -> i64, 363 #[doc = "Try convert this value into a `u128`."] 364 to_u128 -> u128, 365 #[doc = "Try convert this value into a `i128`."] 366 to_i128 -> i128, 367 #[doc = "Try convert this value into a `f64`."] 368 to_f64 -> f64, 369 #[doc = "Try convert this value into a `char`."] 370 to_char -> char, 371 #[doc = "Try convert this value into a `bool`."] 372 to_bool -> bool, 373 ]; 374 375 impl<'v> Value<'v> { 376 /// Try convert this value into an error. 377 #[cfg(feature = "kv_std")] to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)>378 pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> { 379 self.inner.to_borrowed_error() 380 } 381 382 /// Try convert this value into a borrowed string. to_borrowed_str(&self) -> Option<&str>383 pub fn to_borrowed_str(&self) -> Option<&str> { 384 self.inner.to_borrowed_str() 385 } 386 } 387 388 #[cfg(feature = "kv_std")] 389 mod std_support { 390 use std::borrow::Cow; 391 use std::rc::Rc; 392 use std::sync::Arc; 393 394 use super::*; 395 396 impl<T> ToValue for Box<T> 397 where 398 T: ToValue + ?Sized, 399 { to_value(&self) -> Value400 fn to_value(&self) -> Value { 401 (**self).to_value() 402 } 403 } 404 405 impl<T> ToValue for Arc<T> 406 where 407 T: ToValue + ?Sized, 408 { to_value(&self) -> Value409 fn to_value(&self) -> Value { 410 (**self).to_value() 411 } 412 } 413 414 impl<T> ToValue for Rc<T> 415 where 416 T: ToValue + ?Sized, 417 { to_value(&self) -> Value418 fn to_value(&self) -> Value { 419 (**self).to_value() 420 } 421 } 422 423 impl ToValue for String { to_value(&self) -> Value424 fn to_value(&self) -> Value { 425 Value::from(&**self) 426 } 427 } 428 429 impl<'v> ToValue for Cow<'v, str> { to_value(&self) -> Value430 fn to_value(&self) -> Value { 431 Value::from(&**self) 432 } 433 } 434 435 impl<'v> Value<'v> { 436 /// Try convert this value into a string. to_cow_str(&self) -> Option<Cow<'v, str>>437 pub fn to_cow_str(&self) -> Option<Cow<'v, str>> { 438 self.inner.to_str() 439 } 440 } 441 442 impl<'v> From<&'v String> for Value<'v> { from(v: &'v String) -> Self443 fn from(v: &'v String) -> Self { 444 Value::from(&**v) 445 } 446 } 447 } 448 449 /// A visitor for a [`Value`]. 450 /// 451 /// Also see [`Value`'s documentation on seralization]. Value visitors are a simple alternative 452 /// to a more fully-featured serialization framework like `serde` or `sval`. A value visitor 453 /// can differentiate primitive types through methods like [`VisitValue::visit_bool`] and 454 /// [`VisitValue::visit_str`], but more complex types like maps and sequences 455 /// will fallthrough to [`VisitValue::visit_any`]. 456 /// 457 /// If you're trying to serialize a value to a format like JSON, you can use either `serde` 458 /// or `sval` directly with the value. You don't need a visitor. 459 /// 460 /// [`Value`'s documentation on seralization]: Value#serialization 461 pub trait VisitValue<'v> { 462 /// Visit a `Value`. 463 /// 464 /// This is the only required method on `VisitValue` and acts as a fallback for any 465 /// more specific methods that aren't overridden. 466 /// The `Value` may be formatted using its `fmt::Debug` or `fmt::Display` implementation, 467 /// or serialized using its `sval::Value` or `serde::Serialize` implementation. visit_any(&mut self, value: Value) -> Result<(), Error>468 fn visit_any(&mut self, value: Value) -> Result<(), Error>; 469 470 /// Visit an empty value. visit_null(&mut self) -> Result<(), Error>471 fn visit_null(&mut self) -> Result<(), Error> { 472 self.visit_any(Value::null()) 473 } 474 475 /// Visit an unsigned integer. visit_u64(&mut self, value: u64) -> Result<(), Error>476 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 477 self.visit_any(value.into()) 478 } 479 480 /// Visit a signed integer. visit_i64(&mut self, value: i64) -> Result<(), Error>481 fn visit_i64(&mut self, value: i64) -> Result<(), Error> { 482 self.visit_any(value.into()) 483 } 484 485 /// Visit a big unsigned integer. visit_u128(&mut self, value: u128) -> Result<(), Error>486 fn visit_u128(&mut self, value: u128) -> Result<(), Error> { 487 self.visit_any((value).into()) 488 } 489 490 /// Visit a big signed integer. visit_i128(&mut self, value: i128) -> Result<(), Error>491 fn visit_i128(&mut self, value: i128) -> Result<(), Error> { 492 self.visit_any((value).into()) 493 } 494 495 /// Visit a floating point. visit_f64(&mut self, value: f64) -> Result<(), Error>496 fn visit_f64(&mut self, value: f64) -> Result<(), Error> { 497 self.visit_any(value.into()) 498 } 499 500 /// Visit a boolean. visit_bool(&mut self, value: bool) -> Result<(), Error>501 fn visit_bool(&mut self, value: bool) -> Result<(), Error> { 502 self.visit_any(value.into()) 503 } 504 505 /// Visit a string. visit_str(&mut self, value: &str) -> Result<(), Error>506 fn visit_str(&mut self, value: &str) -> Result<(), Error> { 507 self.visit_any(value.into()) 508 } 509 510 /// Visit a string. visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error>511 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 512 self.visit_str(value) 513 } 514 515 /// Visit a Unicode character. visit_char(&mut self, value: char) -> Result<(), Error>516 fn visit_char(&mut self, value: char) -> Result<(), Error> { 517 let mut b = [0; 4]; 518 self.visit_str(&*value.encode_utf8(&mut b)) 519 } 520 521 /// Visit an error. 522 #[cfg(feature = "kv_std")] visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error>523 fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> { 524 self.visit_any(Value::from_dyn_error(err)) 525 } 526 527 /// Visit an error. 528 #[cfg(feature = "kv_std")] visit_borrowed_error( &mut self, err: &'v (dyn std::error::Error + 'static), ) -> Result<(), Error>529 fn visit_borrowed_error( 530 &mut self, 531 err: &'v (dyn std::error::Error + 'static), 532 ) -> Result<(), Error> { 533 self.visit_any(Value::from_dyn_error(err)) 534 } 535 } 536 537 impl<'a, 'v, T: ?Sized> VisitValue<'v> for &'a mut T 538 where 539 T: VisitValue<'v>, 540 { visit_any(&mut self, value: Value) -> Result<(), Error>541 fn visit_any(&mut self, value: Value) -> Result<(), Error> { 542 (**self).visit_any(value) 543 } 544 visit_null(&mut self) -> Result<(), Error>545 fn visit_null(&mut self) -> Result<(), Error> { 546 (**self).visit_null() 547 } 548 visit_u64(&mut self, value: u64) -> Result<(), Error>549 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 550 (**self).visit_u64(value) 551 } 552 visit_i64(&mut self, value: i64) -> Result<(), Error>553 fn visit_i64(&mut self, value: i64) -> Result<(), Error> { 554 (**self).visit_i64(value) 555 } 556 visit_u128(&mut self, value: u128) -> Result<(), Error>557 fn visit_u128(&mut self, value: u128) -> Result<(), Error> { 558 (**self).visit_u128(value) 559 } 560 visit_i128(&mut self, value: i128) -> Result<(), Error>561 fn visit_i128(&mut self, value: i128) -> Result<(), Error> { 562 (**self).visit_i128(value) 563 } 564 visit_f64(&mut self, value: f64) -> Result<(), Error>565 fn visit_f64(&mut self, value: f64) -> Result<(), Error> { 566 (**self).visit_f64(value) 567 } 568 visit_bool(&mut self, value: bool) -> Result<(), Error>569 fn visit_bool(&mut self, value: bool) -> Result<(), Error> { 570 (**self).visit_bool(value) 571 } 572 visit_str(&mut self, value: &str) -> Result<(), Error>573 fn visit_str(&mut self, value: &str) -> Result<(), Error> { 574 (**self).visit_str(value) 575 } 576 visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error>577 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 578 (**self).visit_borrowed_str(value) 579 } 580 visit_char(&mut self, value: char) -> Result<(), Error>581 fn visit_char(&mut self, value: char) -> Result<(), Error> { 582 (**self).visit_char(value) 583 } 584 585 #[cfg(feature = "kv_std")] visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error>586 fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> { 587 (**self).visit_error(err) 588 } 589 590 #[cfg(feature = "kv_std")] visit_borrowed_error( &mut self, err: &'v (dyn std::error::Error + 'static), ) -> Result<(), Error>591 fn visit_borrowed_error( 592 &mut self, 593 err: &'v (dyn std::error::Error + 'static), 594 ) -> Result<(), Error> { 595 (**self).visit_borrowed_error(err) 596 } 597 } 598 599 #[cfg(feature = "value-bag")] 600 pub(in crate::kv) mod inner { 601 /** 602 An implementation of `Value` based on a library called `value_bag`. 603 604 `value_bag` was written specifically for use in `log`'s value, but was split out when it outgrew 605 the codebase here. It's a general-purpose type-erasure library that handles mapping between 606 more fully-featured serialization frameworks. 607 */ 608 use super::*; 609 610 pub use value_bag::ValueBag as Inner; 611 612 pub use value_bag::Error; 613 614 #[cfg(test)] 615 pub use value_bag::test::TestToken as Token; 616 visit<'v>( inner: &Inner<'v>, visitor: impl VisitValue<'v>, ) -> Result<(), crate::kv::Error>617 pub fn visit<'v>( 618 inner: &Inner<'v>, 619 visitor: impl VisitValue<'v>, 620 ) -> Result<(), crate::kv::Error> { 621 struct InnerVisitValue<V>(V); 622 623 impl<'v, V> value_bag::visit::Visit<'v> for InnerVisitValue<V> 624 where 625 V: VisitValue<'v>, 626 { 627 fn visit_any(&mut self, value: value_bag::ValueBag) -> Result<(), Error> { 628 self.0 629 .visit_any(Value { inner: value }) 630 .map_err(crate::kv::Error::into_value) 631 } 632 633 fn visit_empty(&mut self) -> Result<(), Error> { 634 self.0.visit_null().map_err(crate::kv::Error::into_value) 635 } 636 637 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 638 self.0 639 .visit_u64(value) 640 .map_err(crate::kv::Error::into_value) 641 } 642 643 fn visit_i64(&mut self, value: i64) -> Result<(), Error> { 644 self.0 645 .visit_i64(value) 646 .map_err(crate::kv::Error::into_value) 647 } 648 649 fn visit_u128(&mut self, value: u128) -> Result<(), Error> { 650 self.0 651 .visit_u128(value) 652 .map_err(crate::kv::Error::into_value) 653 } 654 655 fn visit_i128(&mut self, value: i128) -> Result<(), Error> { 656 self.0 657 .visit_i128(value) 658 .map_err(crate::kv::Error::into_value) 659 } 660 661 fn visit_f64(&mut self, value: f64) -> Result<(), Error> { 662 self.0 663 .visit_f64(value) 664 .map_err(crate::kv::Error::into_value) 665 } 666 667 fn visit_bool(&mut self, value: bool) -> Result<(), Error> { 668 self.0 669 .visit_bool(value) 670 .map_err(crate::kv::Error::into_value) 671 } 672 673 fn visit_str(&mut self, value: &str) -> Result<(), Error> { 674 self.0 675 .visit_str(value) 676 .map_err(crate::kv::Error::into_value) 677 } 678 679 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 680 self.0 681 .visit_borrowed_str(value) 682 .map_err(crate::kv::Error::into_value) 683 } 684 685 fn visit_char(&mut self, value: char) -> Result<(), Error> { 686 self.0 687 .visit_char(value) 688 .map_err(crate::kv::Error::into_value) 689 } 690 691 #[cfg(feature = "kv_std")] 692 fn visit_error( 693 &mut self, 694 err: &(dyn std::error::Error + 'static), 695 ) -> Result<(), Error> { 696 self.0 697 .visit_error(err) 698 .map_err(crate::kv::Error::into_value) 699 } 700 701 #[cfg(feature = "kv_std")] 702 fn visit_borrowed_error( 703 &mut self, 704 err: &'v (dyn std::error::Error + 'static), 705 ) -> Result<(), Error> { 706 self.0 707 .visit_borrowed_error(err) 708 .map_err(crate::kv::Error::into_value) 709 } 710 } 711 712 inner 713 .visit(&mut InnerVisitValue(visitor)) 714 .map_err(crate::kv::Error::from_value) 715 } 716 } 717 718 #[cfg(not(feature = "value-bag"))] 719 pub(in crate::kv) mod inner { 720 /** 721 This is a dependency-free implementation of `Value` when there's no serialization frameworks involved. 722 In these simple cases a more fully featured solution like `value_bag` isn't needed, so we avoid pulling it in. 723 724 There are a few things here that need to remain consistent with the `value_bag`-based implementation: 725 726 1. Conversions should always produce the same results. If a conversion here returns `Some`, then 727 the same `value_bag`-based conversion must also. Of particular note here are floats to ints; they're 728 based on the standard library's `TryInto` conversions, which need to be convert to `i32` or `u32`, 729 and then to `f64`. 730 2. VisitValues should always be called in the same way. If a particular type of value calls `visit_i64`, 731 then the same `value_bag`-based visitor must also. 732 */ 733 use super::*; 734 735 #[derive(Clone)] 736 pub enum Inner<'v> { 737 None, 738 Bool(bool), 739 Str(&'v str), 740 Char(char), 741 I64(i64), 742 U64(u64), 743 F64(f64), 744 I128(i128), 745 U128(u128), 746 Debug(&'v dyn fmt::Debug), 747 Display(&'v dyn fmt::Display), 748 } 749 750 impl<'v> From<()> for Inner<'v> { from(_: ()) -> Self751 fn from(_: ()) -> Self { 752 Inner::None 753 } 754 } 755 756 impl<'v> From<bool> for Inner<'v> { from(v: bool) -> Self757 fn from(v: bool) -> Self { 758 Inner::Bool(v) 759 } 760 } 761 762 impl<'v> From<char> for Inner<'v> { from(v: char) -> Self763 fn from(v: char) -> Self { 764 Inner::Char(v) 765 } 766 } 767 768 impl<'v> From<f32> for Inner<'v> { from(v: f32) -> Self769 fn from(v: f32) -> Self { 770 Inner::F64(v as f64) 771 } 772 } 773 774 impl<'v> From<f64> for Inner<'v> { from(v: f64) -> Self775 fn from(v: f64) -> Self { 776 Inner::F64(v) 777 } 778 } 779 780 impl<'v> From<i8> for Inner<'v> { from(v: i8) -> Self781 fn from(v: i8) -> Self { 782 Inner::I64(v as i64) 783 } 784 } 785 786 impl<'v> From<i16> for Inner<'v> { from(v: i16) -> Self787 fn from(v: i16) -> Self { 788 Inner::I64(v as i64) 789 } 790 } 791 792 impl<'v> From<i32> for Inner<'v> { from(v: i32) -> Self793 fn from(v: i32) -> Self { 794 Inner::I64(v as i64) 795 } 796 } 797 798 impl<'v> From<i64> for Inner<'v> { from(v: i64) -> Self799 fn from(v: i64) -> Self { 800 Inner::I64(v as i64) 801 } 802 } 803 804 impl<'v> From<isize> for Inner<'v> { from(v: isize) -> Self805 fn from(v: isize) -> Self { 806 Inner::I64(v as i64) 807 } 808 } 809 810 impl<'v> From<u8> for Inner<'v> { from(v: u8) -> Self811 fn from(v: u8) -> Self { 812 Inner::U64(v as u64) 813 } 814 } 815 816 impl<'v> From<u16> for Inner<'v> { from(v: u16) -> Self817 fn from(v: u16) -> Self { 818 Inner::U64(v as u64) 819 } 820 } 821 822 impl<'v> From<u32> for Inner<'v> { from(v: u32) -> Self823 fn from(v: u32) -> Self { 824 Inner::U64(v as u64) 825 } 826 } 827 828 impl<'v> From<u64> for Inner<'v> { from(v: u64) -> Self829 fn from(v: u64) -> Self { 830 Inner::U64(v as u64) 831 } 832 } 833 834 impl<'v> From<usize> for Inner<'v> { from(v: usize) -> Self835 fn from(v: usize) -> Self { 836 Inner::U64(v as u64) 837 } 838 } 839 840 impl<'v> From<i128> for Inner<'v> { from(v: i128) -> Self841 fn from(v: i128) -> Self { 842 Inner::I128(v) 843 } 844 } 845 846 impl<'v> From<u128> for Inner<'v> { from(v: u128) -> Self847 fn from(v: u128) -> Self { 848 Inner::U128(v) 849 } 850 } 851 852 impl<'v> From<&'v str> for Inner<'v> { from(v: &'v str) -> Self853 fn from(v: &'v str) -> Self { 854 Inner::Str(v) 855 } 856 } 857 858 impl<'v> fmt::Debug for Inner<'v> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result859 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 860 match self { 861 Inner::None => fmt::Debug::fmt(&None::<()>, f), 862 Inner::Bool(v) => fmt::Debug::fmt(v, f), 863 Inner::Str(v) => fmt::Debug::fmt(v, f), 864 Inner::Char(v) => fmt::Debug::fmt(v, f), 865 Inner::I64(v) => fmt::Debug::fmt(v, f), 866 Inner::U64(v) => fmt::Debug::fmt(v, f), 867 Inner::F64(v) => fmt::Debug::fmt(v, f), 868 Inner::I128(v) => fmt::Debug::fmt(v, f), 869 Inner::U128(v) => fmt::Debug::fmt(v, f), 870 Inner::Debug(v) => fmt::Debug::fmt(v, f), 871 Inner::Display(v) => fmt::Display::fmt(v, f), 872 } 873 } 874 } 875 876 impl<'v> fmt::Display for Inner<'v> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result877 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 878 match self { 879 Inner::None => fmt::Debug::fmt(&None::<()>, f), 880 Inner::Bool(v) => fmt::Display::fmt(v, f), 881 Inner::Str(v) => fmt::Display::fmt(v, f), 882 Inner::Char(v) => fmt::Display::fmt(v, f), 883 Inner::I64(v) => fmt::Display::fmt(v, f), 884 Inner::U64(v) => fmt::Display::fmt(v, f), 885 Inner::F64(v) => fmt::Display::fmt(v, f), 886 Inner::I128(v) => fmt::Display::fmt(v, f), 887 Inner::U128(v) => fmt::Display::fmt(v, f), 888 Inner::Debug(v) => fmt::Debug::fmt(v, f), 889 Inner::Display(v) => fmt::Display::fmt(v, f), 890 } 891 } 892 } 893 894 impl<'v> Inner<'v> { from_debug<T: fmt::Debug>(value: &'v T) -> Self895 pub fn from_debug<T: fmt::Debug>(value: &'v T) -> Self { 896 Inner::Debug(value) 897 } 898 from_display<T: fmt::Display>(value: &'v T) -> Self899 pub fn from_display<T: fmt::Display>(value: &'v T) -> Self { 900 Inner::Display(value) 901 } 902 from_dyn_debug(value: &'v dyn fmt::Debug) -> Self903 pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self { 904 Inner::Debug(value) 905 } 906 from_dyn_display(value: &'v dyn fmt::Display) -> Self907 pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self { 908 Inner::Display(value) 909 } 910 empty() -> Self911 pub fn empty() -> Self { 912 Inner::None 913 } 914 to_bool(&self) -> Option<bool>915 pub fn to_bool(&self) -> Option<bool> { 916 match self { 917 Inner::Bool(v) => Some(*v), 918 _ => None, 919 } 920 } 921 to_char(&self) -> Option<char>922 pub fn to_char(&self) -> Option<char> { 923 match self { 924 Inner::Char(v) => Some(*v), 925 _ => None, 926 } 927 } 928 to_f64(&self) -> Option<f64>929 pub fn to_f64(&self) -> Option<f64> { 930 match self { 931 Inner::F64(v) => Some(*v), 932 Inner::I64(v) => { 933 let v: i32 = (*v).try_into().ok()?; 934 v.try_into().ok() 935 } 936 Inner::U64(v) => { 937 let v: u32 = (*v).try_into().ok()?; 938 v.try_into().ok() 939 } 940 Inner::I128(v) => { 941 let v: i32 = (*v).try_into().ok()?; 942 v.try_into().ok() 943 } 944 Inner::U128(v) => { 945 let v: u32 = (*v).try_into().ok()?; 946 v.try_into().ok() 947 } 948 _ => None, 949 } 950 } 951 to_i64(&self) -> Option<i64>952 pub fn to_i64(&self) -> Option<i64> { 953 match self { 954 Inner::I64(v) => Some(*v), 955 Inner::U64(v) => (*v).try_into().ok(), 956 Inner::I128(v) => (*v).try_into().ok(), 957 Inner::U128(v) => (*v).try_into().ok(), 958 _ => None, 959 } 960 } 961 to_u64(&self) -> Option<u64>962 pub fn to_u64(&self) -> Option<u64> { 963 match self { 964 Inner::U64(v) => Some(*v), 965 Inner::I64(v) => (*v).try_into().ok(), 966 Inner::I128(v) => (*v).try_into().ok(), 967 Inner::U128(v) => (*v).try_into().ok(), 968 _ => None, 969 } 970 } 971 to_u128(&self) -> Option<u128>972 pub fn to_u128(&self) -> Option<u128> { 973 match self { 974 Inner::U128(v) => Some(*v), 975 Inner::I64(v) => (*v).try_into().ok(), 976 Inner::U64(v) => (*v).try_into().ok(), 977 Inner::I128(v) => (*v).try_into().ok(), 978 _ => None, 979 } 980 } 981 to_i128(&self) -> Option<i128>982 pub fn to_i128(&self) -> Option<i128> { 983 match self { 984 Inner::I128(v) => Some(*v), 985 Inner::I64(v) => (*v).try_into().ok(), 986 Inner::U64(v) => (*v).try_into().ok(), 987 Inner::U128(v) => (*v).try_into().ok(), 988 _ => None, 989 } 990 } 991 to_borrowed_str(&self) -> Option<&'v str>992 pub fn to_borrowed_str(&self) -> Option<&'v str> { 993 match self { 994 Inner::Str(v) => Some(v), 995 _ => None, 996 } 997 } 998 999 #[cfg(test)] to_test_token(&self) -> Token1000 pub fn to_test_token(&self) -> Token { 1001 match self { 1002 Inner::None => Token::None, 1003 Inner::Bool(v) => Token::Bool(*v), 1004 Inner::Str(v) => Token::Str(*v), 1005 Inner::Char(v) => Token::Char(*v), 1006 Inner::I64(v) => Token::I64(*v), 1007 Inner::U64(v) => Token::U64(*v), 1008 Inner::F64(v) => Token::F64(*v), 1009 Inner::I128(_) => unimplemented!(), 1010 Inner::U128(_) => unimplemented!(), 1011 Inner::Debug(_) => unimplemented!(), 1012 Inner::Display(_) => unimplemented!(), 1013 } 1014 } 1015 } 1016 1017 #[cfg(test)] 1018 #[derive(Debug, PartialEq)] 1019 pub enum Token<'v> { 1020 None, 1021 Bool(bool), 1022 Char(char), 1023 Str(&'v str), 1024 F64(f64), 1025 I64(i64), 1026 U64(u64), 1027 } 1028 visit<'v>( inner: &Inner<'v>, mut visitor: impl VisitValue<'v>, ) -> Result<(), crate::kv::Error>1029 pub fn visit<'v>( 1030 inner: &Inner<'v>, 1031 mut visitor: impl VisitValue<'v>, 1032 ) -> Result<(), crate::kv::Error> { 1033 match inner { 1034 Inner::None => visitor.visit_null(), 1035 Inner::Bool(v) => visitor.visit_bool(*v), 1036 Inner::Str(v) => visitor.visit_borrowed_str(*v), 1037 Inner::Char(v) => visitor.visit_char(*v), 1038 Inner::I64(v) => visitor.visit_i64(*v), 1039 Inner::U64(v) => visitor.visit_u64(*v), 1040 Inner::F64(v) => visitor.visit_f64(*v), 1041 Inner::I128(v) => visitor.visit_i128(*v), 1042 Inner::U128(v) => visitor.visit_u128(*v), 1043 Inner::Debug(v) => visitor.visit_any(Value::from_dyn_debug(*v)), 1044 Inner::Display(v) => visitor.visit_any(Value::from_dyn_display(*v)), 1045 } 1046 } 1047 } 1048 1049 impl<'v> Value<'v> { 1050 /// Get a value from a type implementing `std::fmt::Debug`. 1051 #[cfg(feature = "kv_unstable")] 1052 #[deprecated(note = "use `from_debug` instead")] capture_debug<T>(value: &'v T) -> Self where T: fmt::Debug + 'static,1053 pub fn capture_debug<T>(value: &'v T) -> Self 1054 where 1055 T: fmt::Debug + 'static, 1056 { 1057 Value::from_debug(value) 1058 } 1059 1060 /// Get a value from a type implementing `std::fmt::Display`. 1061 #[cfg(feature = "kv_unstable")] 1062 #[deprecated(note = "use `from_display` instead")] capture_display<T>(value: &'v T) -> Self where T: fmt::Display + 'static,1063 pub fn capture_display<T>(value: &'v T) -> Self 1064 where 1065 T: fmt::Display + 'static, 1066 { 1067 Value::from_display(value) 1068 } 1069 1070 /// Get a value from an error. 1071 #[cfg(feature = "kv_unstable_std")] 1072 #[deprecated(note = "use `from_dyn_error` instead")] capture_error<T>(err: &'v T) -> Self where T: std::error::Error + 'static,1073 pub fn capture_error<T>(err: &'v T) -> Self 1074 where 1075 T: std::error::Error + 'static, 1076 { 1077 Value::from_dyn_error(err) 1078 } 1079 1080 /// Get a value from a type implementing `serde::Serialize`. 1081 #[cfg(feature = "kv_unstable_serde")] 1082 #[deprecated(note = "use `from_serde` instead")] capture_serde<T>(value: &'v T) -> Self where T: serde::Serialize + 'static,1083 pub fn capture_serde<T>(value: &'v T) -> Self 1084 where 1085 T: serde::Serialize + 'static, 1086 { 1087 Value::from_serde(value) 1088 } 1089 1090 /// Get a value from a type implementing `sval::Value`. 1091 #[cfg(feature = "kv_unstable_sval")] 1092 #[deprecated(note = "use `from_sval` instead")] capture_sval<T>(value: &'v T) -> Self where T: sval::Value + 'static,1093 pub fn capture_sval<T>(value: &'v T) -> Self 1094 where 1095 T: sval::Value + 'static, 1096 { 1097 Value::from_sval(value) 1098 } 1099 1100 /// Check whether this value can be downcast to `T`. 1101 #[cfg(feature = "kv_unstable")] 1102 #[deprecated( 1103 note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on" 1104 )] is<T: 'static>(&self) -> bool1105 pub fn is<T: 'static>(&self) -> bool { 1106 false 1107 } 1108 1109 /// Try downcast this value to `T`. 1110 #[cfg(feature = "kv_unstable")] 1111 #[deprecated( 1112 note = "downcasting has been removed; log an issue at https://github.com/rust-lang/log/issues if this is something you rely on" 1113 )] downcast_ref<T: 'static>(&self) -> Option<&T>1114 pub fn downcast_ref<T: 'static>(&self) -> Option<&T> { 1115 None 1116 } 1117 } 1118 1119 // NOTE: Deprecated; but aliases can't carry this attribute 1120 #[cfg(feature = "kv_unstable")] 1121 pub use VisitValue as Visit; 1122 1123 /// Get a value from a type implementing `std::fmt::Debug`. 1124 #[cfg(feature = "kv_unstable")] 1125 #[deprecated(note = "use the `key:? = value` macro syntax instead")] 1126 #[macro_export] 1127 macro_rules! as_debug { 1128 ($capture:expr) => { 1129 $crate::kv::Value::from_debug(&$capture) 1130 }; 1131 } 1132 1133 /// Get a value from a type implementing `std::fmt::Display`. 1134 #[cfg(feature = "kv_unstable")] 1135 #[deprecated(note = "use the `key:% = value` macro syntax instead")] 1136 #[macro_export] 1137 macro_rules! as_display { 1138 ($capture:expr) => { 1139 $crate::kv::Value::from_display(&$capture) 1140 }; 1141 } 1142 1143 /// Get a value from an error. 1144 #[cfg(feature = "kv_unstable_std")] 1145 #[deprecated(note = "use the `key:err = value` macro syntax instead")] 1146 #[macro_export] 1147 macro_rules! as_error { 1148 ($capture:expr) => { 1149 $crate::kv::Value::from_dyn_error(&$capture) 1150 }; 1151 } 1152 1153 #[cfg(feature = "kv_unstable_serde")] 1154 #[deprecated(note = "use the `key:serde = value` macro syntax instead")] 1155 /// Get a value from a type implementing `serde::Serialize`. 1156 #[macro_export] 1157 macro_rules! as_serde { 1158 ($capture:expr) => { 1159 $crate::kv::Value::from_serde(&$capture) 1160 }; 1161 } 1162 1163 /// Get a value from a type implementing `sval::Value`. 1164 #[cfg(feature = "kv_unstable_sval")] 1165 #[deprecated(note = "use the `key:sval = value` macro syntax instead")] 1166 #[macro_export] 1167 macro_rules! as_sval { 1168 ($capture:expr) => { 1169 $crate::kv::Value::from_sval(&$capture) 1170 }; 1171 } 1172 1173 #[cfg(test)] 1174 pub(crate) mod tests { 1175 use super::*; 1176 1177 impl<'v> Value<'v> { to_token(&self) -> inner::Token1178 pub(crate) fn to_token(&self) -> inner::Token { 1179 self.inner.to_test_token() 1180 } 1181 } 1182 unsigned() -> impl Iterator<Item = Value<'static>>1183 fn unsigned() -> impl Iterator<Item = Value<'static>> { 1184 vec![ 1185 Value::from(8u8), 1186 Value::from(16u16), 1187 Value::from(32u32), 1188 Value::from(64u64), 1189 Value::from(1usize), 1190 Value::from(std::num::NonZeroU8::new(8).unwrap()), 1191 Value::from(std::num::NonZeroU16::new(16).unwrap()), 1192 Value::from(std::num::NonZeroU32::new(32).unwrap()), 1193 Value::from(std::num::NonZeroU64::new(64).unwrap()), 1194 Value::from(std::num::NonZeroUsize::new(1).unwrap()), 1195 ] 1196 .into_iter() 1197 } 1198 signed() -> impl Iterator<Item = Value<'static>>1199 fn signed() -> impl Iterator<Item = Value<'static>> { 1200 vec![ 1201 Value::from(-8i8), 1202 Value::from(-16i16), 1203 Value::from(-32i32), 1204 Value::from(-64i64), 1205 Value::from(-1isize), 1206 Value::from(std::num::NonZeroI8::new(-8).unwrap()), 1207 Value::from(std::num::NonZeroI16::new(-16).unwrap()), 1208 Value::from(std::num::NonZeroI32::new(-32).unwrap()), 1209 Value::from(std::num::NonZeroI64::new(-64).unwrap()), 1210 Value::from(std::num::NonZeroIsize::new(-1).unwrap()), 1211 ] 1212 .into_iter() 1213 } 1214 float() -> impl Iterator<Item = Value<'static>>1215 fn float() -> impl Iterator<Item = Value<'static>> { 1216 vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter() 1217 } 1218 bool() -> impl Iterator<Item = Value<'static>>1219 fn bool() -> impl Iterator<Item = Value<'static>> { 1220 vec![Value::from(true), Value::from(false)].into_iter() 1221 } 1222 str() -> impl Iterator<Item = Value<'static>>1223 fn str() -> impl Iterator<Item = Value<'static>> { 1224 vec![Value::from("a string"), Value::from("a loong string")].into_iter() 1225 } 1226 char() -> impl Iterator<Item = Value<'static>>1227 fn char() -> impl Iterator<Item = Value<'static>> { 1228 vec![Value::from('a'), Value::from('⛰')].into_iter() 1229 } 1230 1231 #[test] test_to_value_display()1232 fn test_to_value_display() { 1233 assert_eq!(42u64.to_value().to_string(), "42"); 1234 assert_eq!(42i64.to_value().to_string(), "42"); 1235 assert_eq!(42.01f64.to_value().to_string(), "42.01"); 1236 assert_eq!(true.to_value().to_string(), "true"); 1237 assert_eq!('a'.to_value().to_string(), "a"); 1238 assert_eq!("a loong string".to_value().to_string(), "a loong string"); 1239 assert_eq!(Some(true).to_value().to_string(), "true"); 1240 assert_eq!(().to_value().to_string(), "None"); 1241 assert_eq!(None::<bool>.to_value().to_string(), "None"); 1242 } 1243 1244 #[test] test_to_value_structured()1245 fn test_to_value_structured() { 1246 assert_eq!(42u64.to_value().to_token(), inner::Token::U64(42)); 1247 assert_eq!(42i64.to_value().to_token(), inner::Token::I64(42)); 1248 assert_eq!(42.01f64.to_value().to_token(), inner::Token::F64(42.01)); 1249 assert_eq!(true.to_value().to_token(), inner::Token::Bool(true)); 1250 assert_eq!('a'.to_value().to_token(), inner::Token::Char('a')); 1251 assert_eq!( 1252 "a loong string".to_value().to_token(), 1253 inner::Token::Str("a loong string".into()) 1254 ); 1255 assert_eq!(Some(true).to_value().to_token(), inner::Token::Bool(true)); 1256 assert_eq!(().to_value().to_token(), inner::Token::None); 1257 assert_eq!(None::<bool>.to_value().to_token(), inner::Token::None); 1258 } 1259 1260 #[test] test_to_number()1261 fn test_to_number() { 1262 for v in unsigned() { 1263 assert!(v.to_u64().is_some()); 1264 assert!(v.to_i64().is_some()); 1265 } 1266 1267 for v in signed() { 1268 assert!(v.to_i64().is_some()); 1269 } 1270 1271 for v in unsigned().chain(signed()).chain(float()) { 1272 assert!(v.to_f64().is_some()); 1273 } 1274 1275 for v in bool().chain(str()).chain(char()) { 1276 assert!(v.to_u64().is_none()); 1277 assert!(v.to_i64().is_none()); 1278 assert!(v.to_f64().is_none()); 1279 } 1280 } 1281 1282 #[test] test_to_float()1283 fn test_to_float() { 1284 // Only integers from i32::MIN..=u32::MAX can be converted into floats 1285 assert!(Value::from(i32::MIN).to_f64().is_some()); 1286 assert!(Value::from(u32::MAX).to_f64().is_some()); 1287 1288 assert!(Value::from((i32::MIN as i64) - 1).to_f64().is_none()); 1289 assert!(Value::from((u32::MAX as u64) + 1).to_f64().is_none()); 1290 } 1291 1292 #[test] test_to_cow_str()1293 fn test_to_cow_str() { 1294 for v in str() { 1295 assert!(v.to_borrowed_str().is_some()); 1296 1297 #[cfg(feature = "kv_std")] 1298 assert!(v.to_cow_str().is_some()); 1299 } 1300 1301 let short_lived = String::from("short lived"); 1302 let v = Value::from(&*short_lived); 1303 1304 assert!(v.to_borrowed_str().is_some()); 1305 1306 #[cfg(feature = "kv_std")] 1307 assert!(v.to_cow_str().is_some()); 1308 1309 for v in unsigned().chain(signed()).chain(float()).chain(bool()) { 1310 assert!(v.to_borrowed_str().is_none()); 1311 1312 #[cfg(feature = "kv_std")] 1313 assert!(v.to_cow_str().is_none()); 1314 } 1315 } 1316 1317 #[test] test_to_bool()1318 fn test_to_bool() { 1319 for v in bool() { 1320 assert!(v.to_bool().is_some()); 1321 } 1322 1323 for v in unsigned() 1324 .chain(signed()) 1325 .chain(float()) 1326 .chain(str()) 1327 .chain(char()) 1328 { 1329 assert!(v.to_bool().is_none()); 1330 } 1331 } 1332 1333 #[test] test_to_char()1334 fn test_to_char() { 1335 for v in char() { 1336 assert!(v.to_char().is_some()); 1337 } 1338 1339 for v in unsigned() 1340 .chain(signed()) 1341 .chain(float()) 1342 .chain(str()) 1343 .chain(bool()) 1344 { 1345 assert!(v.to_char().is_none()); 1346 } 1347 } 1348 1349 #[test] test_visit_integer()1350 fn test_visit_integer() { 1351 struct Extract(Option<u64>); 1352 1353 impl<'v> VisitValue<'v> for Extract { 1354 fn visit_any(&mut self, value: Value) -> Result<(), Error> { 1355 unimplemented!("unexpected value: {value:?}") 1356 } 1357 1358 fn visit_u64(&mut self, value: u64) -> Result<(), Error> { 1359 self.0 = Some(value); 1360 1361 Ok(()) 1362 } 1363 } 1364 1365 let mut extract = Extract(None); 1366 Value::from(42u64).visit(&mut extract).unwrap(); 1367 1368 assert_eq!(Some(42), extract.0); 1369 } 1370 1371 #[test] test_visit_borrowed_str()1372 fn test_visit_borrowed_str() { 1373 struct Extract<'v>(Option<&'v str>); 1374 1375 impl<'v> VisitValue<'v> for Extract<'v> { 1376 fn visit_any(&mut self, value: Value) -> Result<(), Error> { 1377 unimplemented!("unexpected value: {value:?}") 1378 } 1379 1380 fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { 1381 self.0 = Some(value); 1382 1383 Ok(()) 1384 } 1385 } 1386 1387 let mut extract = Extract(None); 1388 1389 let short_lived = String::from("A short-lived string"); 1390 Value::from(&*short_lived).visit(&mut extract).unwrap(); 1391 1392 assert_eq!(Some("A short-lived string"), extract.0); 1393 } 1394 } 1395