1 use std::convert::TryInto; 2 use std::fmt; 3 use std::fmt::Display; 4 5 use serde::de::{Deserialize, Deserializer, Visitor}; 6 7 use crate::error::{ConfigError, Result, Unexpected}; 8 use crate::map::Map; 9 10 /// Underlying kind of the configuration value. 11 /// 12 /// Standard operations on a `Value` by users of this crate do not require 13 /// knowledge of `ValueKind`. Introspection of underlying kind is only required 14 /// when the configuration values are unstructured or do not have known types. 15 #[derive(Debug, Clone, PartialEq)] 16 pub enum ValueKind { 17 Nil, 18 Boolean(bool), 19 I64(i64), 20 I128(i128), 21 U64(u64), 22 U128(u128), 23 Float(f64), 24 String(String), 25 Table(Table), 26 Array(Array), 27 } 28 29 pub type Array = Vec<Value>; 30 pub type Table = Map<String, Value>; 31 32 impl Default for ValueKind { default() -> Self33 fn default() -> Self { 34 Self::Nil 35 } 36 } 37 38 impl<T> From<Option<T>> for ValueKind 39 where 40 T: Into<Self>, 41 { from(value: Option<T>) -> Self42 fn from(value: Option<T>) -> Self { 43 match value { 44 Some(value) => value.into(), 45 None => Self::Nil, 46 } 47 } 48 } 49 50 impl From<String> for ValueKind { from(value: String) -> Self51 fn from(value: String) -> Self { 52 Self::String(value) 53 } 54 } 55 56 impl<'a> From<&'a str> for ValueKind { from(value: &'a str) -> Self57 fn from(value: &'a str) -> Self { 58 Self::String(value.into()) 59 } 60 } 61 62 impl From<i8> for ValueKind { from(value: i8) -> Self63 fn from(value: i8) -> Self { 64 Self::I64(value.into()) 65 } 66 } 67 68 impl From<i16> for ValueKind { from(value: i16) -> Self69 fn from(value: i16) -> Self { 70 Self::I64(value.into()) 71 } 72 } 73 74 impl From<i32> for ValueKind { from(value: i32) -> Self75 fn from(value: i32) -> Self { 76 Self::I64(value.into()) 77 } 78 } 79 80 impl From<i64> for ValueKind { from(value: i64) -> Self81 fn from(value: i64) -> Self { 82 Self::I64(value) 83 } 84 } 85 86 impl From<i128> for ValueKind { from(value: i128) -> Self87 fn from(value: i128) -> Self { 88 Self::I128(value) 89 } 90 } 91 92 impl From<u8> for ValueKind { from(value: u8) -> Self93 fn from(value: u8) -> Self { 94 Self::U64(value.into()) 95 } 96 } 97 98 impl From<u16> for ValueKind { from(value: u16) -> Self99 fn from(value: u16) -> Self { 100 Self::U64(value.into()) 101 } 102 } 103 104 impl From<u32> for ValueKind { from(value: u32) -> Self105 fn from(value: u32) -> Self { 106 Self::U64(value.into()) 107 } 108 } 109 110 impl From<u64> for ValueKind { from(value: u64) -> Self111 fn from(value: u64) -> Self { 112 Self::U64(value) 113 } 114 } 115 116 impl From<u128> for ValueKind { from(value: u128) -> Self117 fn from(value: u128) -> Self { 118 Self::U128(value) 119 } 120 } 121 122 impl From<f64> for ValueKind { from(value: f64) -> Self123 fn from(value: f64) -> Self { 124 Self::Float(value) 125 } 126 } 127 128 impl From<bool> for ValueKind { from(value: bool) -> Self129 fn from(value: bool) -> Self { 130 Self::Boolean(value) 131 } 132 } 133 134 impl<T> From<Map<String, T>> for ValueKind 135 where 136 T: Into<Value>, 137 { from(values: Map<String, T>) -> Self138 fn from(values: Map<String, T>) -> Self { 139 let t = values.into_iter().map(|(k, v)| (k, v.into())).collect(); 140 Self::Table(t) 141 } 142 } 143 144 impl<T> From<Vec<T>> for ValueKind 145 where 146 T: Into<Value>, 147 { from(values: Vec<T>) -> Self148 fn from(values: Vec<T>) -> Self { 149 Self::Array(values.into_iter().map(T::into).collect()) 150 } 151 } 152 153 impl Display for ValueKind { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 155 match *self { 156 Self::String(ref value) => write!(f, "{}", value), 157 Self::Boolean(value) => write!(f, "{}", value), 158 Self::I64(value) => write!(f, "{}", value), 159 Self::I128(value) => write!(f, "{}", value), 160 Self::U64(value) => write!(f, "{}", value), 161 Self::U128(value) => write!(f, "{}", value), 162 Self::Float(value) => write!(f, "{}", value), 163 Self::Nil => write!(f, "nil"), 164 Self::Table(ref table) => write!(f, "{{ {} }}", { 165 table 166 .iter() 167 .map(|(k, v)| format!("{} => {}, ", k, v)) 168 .collect::<String>() 169 }), 170 Self::Array(ref array) => write!(f, "{:?}", { 171 array.iter().map(|e| format!("{}, ", e)).collect::<String>() 172 }), 173 } 174 } 175 } 176 177 /// A configuration value. 178 #[derive(Default, Debug, Clone, PartialEq)] 179 pub struct Value { 180 /// A description of the original location of the value. 181 /// 182 /// A Value originating from a File might contain: 183 /// ```text 184 /// Settings.toml 185 /// ``` 186 /// 187 /// A Value originating from the environment would contain: 188 /// ```text 189 /// the envrionment 190 /// ``` 191 /// 192 /// A Value originating from a remote source might contain: 193 /// ```text 194 /// etcd+http://127.0.0.1:2379 195 /// ``` 196 origin: Option<String>, 197 198 /// Underlying kind of the configuration value. 199 pub kind: ValueKind, 200 } 201 202 impl Value { 203 /// Create a new value instance that will remember its source uri. new<V>(origin: Option<&String>, kind: V) -> Self where V: Into<ValueKind>,204 pub fn new<V>(origin: Option<&String>, kind: V) -> Self 205 where 206 V: Into<ValueKind>, 207 { 208 Self { 209 origin: origin.cloned(), 210 kind: kind.into(), 211 } 212 } 213 214 /// Attempt to deserialize this value into the requested type. try_deserialize<'de, T: Deserialize<'de>>(self) -> Result<T>215 pub fn try_deserialize<'de, T: Deserialize<'de>>(self) -> Result<T> { 216 T::deserialize(self) 217 } 218 219 /// Returns `self` as a bool, if possible. 220 // FIXME: Should this not be `try_into_*` ? into_bool(self) -> Result<bool>221 pub fn into_bool(self) -> Result<bool> { 222 match self.kind { 223 ValueKind::Boolean(value) => Ok(value), 224 ValueKind::I64(value) => Ok(value != 0), 225 ValueKind::I128(value) => Ok(value != 0), 226 ValueKind::U64(value) => Ok(value != 0), 227 ValueKind::U128(value) => Ok(value != 0), 228 ValueKind::Float(value) => Ok(value != 0.0), 229 230 ValueKind::String(ref value) => { 231 match value.to_lowercase().as_ref() { 232 "1" | "true" | "on" | "yes" => Ok(true), 233 "0" | "false" | "off" | "no" => Ok(false), 234 235 // Unexpected string value 236 s => Err(ConfigError::invalid_type( 237 self.origin.clone(), 238 Unexpected::Str(s.into()), 239 "a boolean", 240 )), 241 } 242 } 243 244 // Unexpected type 245 ValueKind::Nil => Err(ConfigError::invalid_type( 246 self.origin, 247 Unexpected::Unit, 248 "a boolean", 249 )), 250 ValueKind::Table(_) => Err(ConfigError::invalid_type( 251 self.origin, 252 Unexpected::Map, 253 "a boolean", 254 )), 255 ValueKind::Array(_) => Err(ConfigError::invalid_type( 256 self.origin, 257 Unexpected::Seq, 258 "a boolean", 259 )), 260 } 261 } 262 263 /// Returns `self` into an i64, if possible. 264 // FIXME: Should this not be `try_into_*` ? into_int(self) -> Result<i64>265 pub fn into_int(self) -> Result<i64> { 266 match self.kind { 267 ValueKind::I64(value) => Ok(value), 268 ValueKind::I128(value) => value.try_into().map_err(|_| { 269 ConfigError::invalid_type( 270 self.origin, 271 Unexpected::I128(value), 272 "an signed 64 bit or less integer", 273 ) 274 }), 275 ValueKind::U64(value) => value.try_into().map_err(|_| { 276 ConfigError::invalid_type( 277 self.origin, 278 Unexpected::U64(value), 279 "an signed 64 bit or less integer", 280 ) 281 }), 282 ValueKind::U128(value) => value.try_into().map_err(|_| { 283 ConfigError::invalid_type( 284 self.origin, 285 Unexpected::U128(value), 286 "an signed 64 bit or less integer", 287 ) 288 }), 289 290 ValueKind::String(ref s) => { 291 match s.to_lowercase().as_ref() { 292 "true" | "on" | "yes" => Ok(1), 293 "false" | "off" | "no" => Ok(0), 294 _ => { 295 s.parse().map_err(|_| { 296 // Unexpected string 297 ConfigError::invalid_type( 298 self.origin.clone(), 299 Unexpected::Str(s.clone()), 300 "an integer", 301 ) 302 }) 303 } 304 } 305 } 306 307 ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }), 308 ValueKind::Float(value) => Ok(value.round() as i64), 309 310 // Unexpected type 311 ValueKind::Nil => Err(ConfigError::invalid_type( 312 self.origin, 313 Unexpected::Unit, 314 "an integer", 315 )), 316 ValueKind::Table(_) => Err(ConfigError::invalid_type( 317 self.origin, 318 Unexpected::Map, 319 "an integer", 320 )), 321 ValueKind::Array(_) => Err(ConfigError::invalid_type( 322 self.origin, 323 Unexpected::Seq, 324 "an integer", 325 )), 326 } 327 } 328 329 /// Returns `self` into an i128, if possible. into_int128(self) -> Result<i128>330 pub fn into_int128(self) -> Result<i128> { 331 match self.kind { 332 ValueKind::I64(value) => Ok(value.into()), 333 ValueKind::I128(value) => Ok(value), 334 ValueKind::U64(value) => Ok(value.into()), 335 ValueKind::U128(value) => value.try_into().map_err(|_| { 336 ConfigError::invalid_type( 337 self.origin, 338 Unexpected::U128(value), 339 "an signed 128 bit integer", 340 ) 341 }), 342 343 ValueKind::String(ref s) => { 344 match s.to_lowercase().as_ref() { 345 "true" | "on" | "yes" => Ok(1), 346 "false" | "off" | "no" => Ok(0), 347 _ => { 348 s.parse().map_err(|_| { 349 // Unexpected string 350 ConfigError::invalid_type( 351 self.origin.clone(), 352 Unexpected::Str(s.clone()), 353 "an integer", 354 ) 355 }) 356 } 357 } 358 } 359 360 ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }), 361 ValueKind::Float(value) => Ok(value.round() as i128), 362 363 // Unexpected type 364 ValueKind::Nil => Err(ConfigError::invalid_type( 365 self.origin, 366 Unexpected::Unit, 367 "an integer", 368 )), 369 ValueKind::Table(_) => Err(ConfigError::invalid_type( 370 self.origin, 371 Unexpected::Map, 372 "an integer", 373 )), 374 ValueKind::Array(_) => Err(ConfigError::invalid_type( 375 self.origin, 376 Unexpected::Seq, 377 "an integer", 378 )), 379 } 380 } 381 382 /// Returns `self` into an u64, if possible. 383 // FIXME: Should this not be `try_into_*` ? into_uint(self) -> Result<u64>384 pub fn into_uint(self) -> Result<u64> { 385 match self.kind { 386 ValueKind::U64(value) => Ok(value), 387 ValueKind::U128(value) => value.try_into().map_err(|_| { 388 ConfigError::invalid_type( 389 self.origin, 390 Unexpected::U128(value), 391 "an unsigned 64 bit or less integer", 392 ) 393 }), 394 ValueKind::I64(value) => value.try_into().map_err(|_| { 395 ConfigError::invalid_type( 396 self.origin, 397 Unexpected::I64(value), 398 "an unsigned 64 bit or less integer", 399 ) 400 }), 401 ValueKind::I128(value) => value.try_into().map_err(|_| { 402 ConfigError::invalid_type( 403 self.origin, 404 Unexpected::I128(value), 405 "an unsigned 64 bit or less integer", 406 ) 407 }), 408 409 ValueKind::String(ref s) => { 410 match s.to_lowercase().as_ref() { 411 "true" | "on" | "yes" => Ok(1), 412 "false" | "off" | "no" => Ok(0), 413 _ => { 414 s.parse().map_err(|_| { 415 // Unexpected string 416 ConfigError::invalid_type( 417 self.origin.clone(), 418 Unexpected::Str(s.clone()), 419 "an integer", 420 ) 421 }) 422 } 423 } 424 } 425 426 ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }), 427 ValueKind::Float(value) => Ok(value.round() as u64), 428 429 // Unexpected type 430 ValueKind::Nil => Err(ConfigError::invalid_type( 431 self.origin, 432 Unexpected::Unit, 433 "an integer", 434 )), 435 ValueKind::Table(_) => Err(ConfigError::invalid_type( 436 self.origin, 437 Unexpected::Map, 438 "an integer", 439 )), 440 ValueKind::Array(_) => Err(ConfigError::invalid_type( 441 self.origin, 442 Unexpected::Seq, 443 "an integer", 444 )), 445 } 446 } 447 448 /// Returns `self` into an u128, if possible. into_uint128(self) -> Result<u128>449 pub fn into_uint128(self) -> Result<u128> { 450 match self.kind { 451 ValueKind::U64(value) => Ok(value.into()), 452 ValueKind::U128(value) => Ok(value), 453 ValueKind::I64(value) => value.try_into().map_err(|_| { 454 ConfigError::invalid_type( 455 self.origin, 456 Unexpected::I64(value), 457 "an unsigned 128 bit or less integer", 458 ) 459 }), 460 ValueKind::I128(value) => value.try_into().map_err(|_| { 461 ConfigError::invalid_type( 462 self.origin, 463 Unexpected::I128(value), 464 "an unsigned 128 bit or less integer", 465 ) 466 }), 467 468 ValueKind::String(ref s) => { 469 match s.to_lowercase().as_ref() { 470 "true" | "on" | "yes" => Ok(1), 471 "false" | "off" | "no" => Ok(0), 472 _ => { 473 s.parse().map_err(|_| { 474 // Unexpected string 475 ConfigError::invalid_type( 476 self.origin.clone(), 477 Unexpected::Str(s.clone()), 478 "an integer", 479 ) 480 }) 481 } 482 } 483 } 484 485 ValueKind::Boolean(value) => Ok(if value { 1 } else { 0 }), 486 ValueKind::Float(value) => Ok(value.round() as u128), 487 488 // Unexpected type 489 ValueKind::Nil => Err(ConfigError::invalid_type( 490 self.origin, 491 Unexpected::Unit, 492 "an integer", 493 )), 494 ValueKind::Table(_) => Err(ConfigError::invalid_type( 495 self.origin, 496 Unexpected::Map, 497 "an integer", 498 )), 499 ValueKind::Array(_) => Err(ConfigError::invalid_type( 500 self.origin, 501 Unexpected::Seq, 502 "an integer", 503 )), 504 } 505 } 506 507 /// Returns `self` into a f64, if possible. 508 // FIXME: Should this not be `try_into_*` ? into_float(self) -> Result<f64>509 pub fn into_float(self) -> Result<f64> { 510 match self.kind { 511 ValueKind::Float(value) => Ok(value), 512 513 ValueKind::String(ref s) => { 514 match s.to_lowercase().as_ref() { 515 "true" | "on" | "yes" => Ok(1.0), 516 "false" | "off" | "no" => Ok(0.0), 517 _ => { 518 s.parse().map_err(|_| { 519 // Unexpected string 520 ConfigError::invalid_type( 521 self.origin.clone(), 522 Unexpected::Str(s.clone()), 523 "a floating point", 524 ) 525 }) 526 } 527 } 528 } 529 530 ValueKind::I64(value) => Ok(value as f64), 531 ValueKind::I128(value) => Ok(value as f64), 532 ValueKind::U64(value) => Ok(value as f64), 533 ValueKind::U128(value) => Ok(value as f64), 534 ValueKind::Boolean(value) => Ok(if value { 1.0 } else { 0.0 }), 535 536 // Unexpected type 537 ValueKind::Nil => Err(ConfigError::invalid_type( 538 self.origin, 539 Unexpected::Unit, 540 "a floating point", 541 )), 542 ValueKind::Table(_) => Err(ConfigError::invalid_type( 543 self.origin, 544 Unexpected::Map, 545 "a floating point", 546 )), 547 ValueKind::Array(_) => Err(ConfigError::invalid_type( 548 self.origin, 549 Unexpected::Seq, 550 "a floating point", 551 )), 552 } 553 } 554 555 /// Returns `self` into a string, if possible. 556 // FIXME: Should this not be `try_into_*` ? into_string(self) -> Result<String>557 pub fn into_string(self) -> Result<String> { 558 match self.kind { 559 ValueKind::String(value) => Ok(value), 560 561 ValueKind::Boolean(value) => Ok(value.to_string()), 562 ValueKind::I64(value) => Ok(value.to_string()), 563 ValueKind::I128(value) => Ok(value.to_string()), 564 ValueKind::U64(value) => Ok(value.to_string()), 565 ValueKind::U128(value) => Ok(value.to_string()), 566 ValueKind::Float(value) => Ok(value.to_string()), 567 568 // Cannot convert 569 ValueKind::Nil => Err(ConfigError::invalid_type( 570 self.origin, 571 Unexpected::Unit, 572 "a string", 573 )), 574 ValueKind::Table(_) => Err(ConfigError::invalid_type( 575 self.origin, 576 Unexpected::Map, 577 "a string", 578 )), 579 ValueKind::Array(_) => Err(ConfigError::invalid_type( 580 self.origin, 581 Unexpected::Seq, 582 "a string", 583 )), 584 } 585 } 586 587 /// Returns `self` into an array, if possible 588 // FIXME: Should this not be `try_into_*` ? into_array(self) -> Result<Vec<Self>>589 pub fn into_array(self) -> Result<Vec<Self>> { 590 match self.kind { 591 ValueKind::Array(value) => Ok(value), 592 593 // Cannot convert 594 ValueKind::Float(value) => Err(ConfigError::invalid_type( 595 self.origin, 596 Unexpected::Float(value), 597 "an array", 598 )), 599 ValueKind::String(value) => Err(ConfigError::invalid_type( 600 self.origin, 601 Unexpected::Str(value), 602 "an array", 603 )), 604 ValueKind::I64(value) => Err(ConfigError::invalid_type( 605 self.origin, 606 Unexpected::I64(value), 607 "an array", 608 )), 609 ValueKind::I128(value) => Err(ConfigError::invalid_type( 610 self.origin, 611 Unexpected::I128(value), 612 "an array", 613 )), 614 ValueKind::U64(value) => Err(ConfigError::invalid_type( 615 self.origin, 616 Unexpected::U64(value), 617 "an array", 618 )), 619 ValueKind::U128(value) => Err(ConfigError::invalid_type( 620 self.origin, 621 Unexpected::U128(value), 622 "an array", 623 )), 624 ValueKind::Boolean(value) => Err(ConfigError::invalid_type( 625 self.origin, 626 Unexpected::Bool(value), 627 "an array", 628 )), 629 ValueKind::Nil => Err(ConfigError::invalid_type( 630 self.origin, 631 Unexpected::Unit, 632 "an array", 633 )), 634 ValueKind::Table(_) => Err(ConfigError::invalid_type( 635 self.origin, 636 Unexpected::Map, 637 "an array", 638 )), 639 } 640 } 641 642 /// If the `Value` is a Table, returns the associated Map. 643 // FIXME: Should this not be `try_into_*` ? into_table(self) -> Result<Map<String, Self>>644 pub fn into_table(self) -> Result<Map<String, Self>> { 645 match self.kind { 646 ValueKind::Table(value) => Ok(value), 647 648 // Cannot convert 649 ValueKind::Float(value) => Err(ConfigError::invalid_type( 650 self.origin, 651 Unexpected::Float(value), 652 "a map", 653 )), 654 ValueKind::String(value) => Err(ConfigError::invalid_type( 655 self.origin, 656 Unexpected::Str(value), 657 "a map", 658 )), 659 ValueKind::I64(value) => Err(ConfigError::invalid_type( 660 self.origin, 661 Unexpected::I64(value), 662 "a map", 663 )), 664 ValueKind::I128(value) => Err(ConfigError::invalid_type( 665 self.origin, 666 Unexpected::I128(value), 667 "a map", 668 )), 669 ValueKind::U64(value) => Err(ConfigError::invalid_type( 670 self.origin, 671 Unexpected::U64(value), 672 "a map", 673 )), 674 ValueKind::U128(value) => Err(ConfigError::invalid_type( 675 self.origin, 676 Unexpected::U128(value), 677 "a map", 678 )), 679 ValueKind::Boolean(value) => Err(ConfigError::invalid_type( 680 self.origin, 681 Unexpected::Bool(value), 682 "a map", 683 )), 684 ValueKind::Nil => Err(ConfigError::invalid_type( 685 self.origin, 686 Unexpected::Unit, 687 "a map", 688 )), 689 ValueKind::Array(_) => Err(ConfigError::invalid_type( 690 self.origin, 691 Unexpected::Seq, 692 "a map", 693 )), 694 } 695 } 696 } 697 698 impl<'de> Deserialize<'de> for Value { 699 #[inline] deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where D: Deserializer<'de>,700 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> 701 where 702 D: Deserializer<'de>, 703 { 704 struct ValueVisitor; 705 706 impl<'de> Visitor<'de> for ValueVisitor { 707 type Value = Value; 708 709 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 710 formatter.write_str("any valid configuration value") 711 } 712 713 #[inline] 714 fn visit_bool<E>(self, value: bool) -> ::std::result::Result<Value, E> { 715 Ok(value.into()) 716 } 717 718 #[inline] 719 fn visit_i8<E>(self, value: i8) -> ::std::result::Result<Value, E> { 720 Ok((i64::from(value)).into()) 721 } 722 723 #[inline] 724 fn visit_i16<E>(self, value: i16) -> ::std::result::Result<Value, E> { 725 Ok((i64::from(value)).into()) 726 } 727 728 #[inline] 729 fn visit_i32<E>(self, value: i32) -> ::std::result::Result<Value, E> { 730 Ok((i64::from(value)).into()) 731 } 732 733 #[inline] 734 fn visit_i64<E>(self, value: i64) -> ::std::result::Result<Value, E> { 735 Ok(value.into()) 736 } 737 738 #[inline] 739 fn visit_i128<E>(self, value: i128) -> ::std::result::Result<Value, E> { 740 Ok(value.into()) 741 } 742 743 #[inline] 744 fn visit_u8<E>(self, value: u8) -> ::std::result::Result<Value, E> { 745 Ok((i64::from(value)).into()) 746 } 747 748 #[inline] 749 fn visit_u16<E>(self, value: u16) -> ::std::result::Result<Value, E> { 750 Ok((i64::from(value)).into()) 751 } 752 753 #[inline] 754 fn visit_u32<E>(self, value: u32) -> ::std::result::Result<Value, E> { 755 Ok((i64::from(value)).into()) 756 } 757 758 #[inline] 759 fn visit_u64<E>(self, value: u64) -> ::std::result::Result<Value, E> { 760 // FIXME: This is bad 761 Ok((value as i64).into()) 762 } 763 764 #[inline] 765 fn visit_u128<E>(self, value: u128) -> ::std::result::Result<Value, E> { 766 // FIXME: This is bad 767 Ok((value as i128).into()) 768 } 769 770 #[inline] 771 fn visit_f64<E>(self, value: f64) -> ::std::result::Result<Value, E> { 772 Ok(value.into()) 773 } 774 775 #[inline] 776 fn visit_str<E>(self, value: &str) -> ::std::result::Result<Value, E> 777 where 778 E: ::serde::de::Error, 779 { 780 self.visit_string(String::from(value)) 781 } 782 783 #[inline] 784 fn visit_string<E>(self, value: String) -> ::std::result::Result<Value, E> { 785 Ok(value.into()) 786 } 787 788 #[inline] 789 fn visit_none<E>(self) -> ::std::result::Result<Value, E> { 790 Ok(Value::new(None, ValueKind::Nil)) 791 } 792 793 #[inline] 794 fn visit_some<D>(self, deserializer: D) -> ::std::result::Result<Value, D::Error> 795 where 796 D: Deserializer<'de>, 797 { 798 Deserialize::deserialize(deserializer) 799 } 800 801 #[inline] 802 fn visit_unit<E>(self) -> ::std::result::Result<Value, E> { 803 Ok(Value::new(None, ValueKind::Nil)) 804 } 805 806 #[inline] 807 fn visit_seq<V>(self, mut visitor: V) -> ::std::result::Result<Value, V::Error> 808 where 809 V: ::serde::de::SeqAccess<'de>, 810 { 811 let mut vec = Array::new(); 812 813 while let Some(elem) = visitor.next_element()? { 814 vec.push(elem); 815 } 816 817 Ok(vec.into()) 818 } 819 820 fn visit_map<V>(self, mut visitor: V) -> ::std::result::Result<Value, V::Error> 821 where 822 V: ::serde::de::MapAccess<'de>, 823 { 824 let mut values = Table::new(); 825 826 while let Some((key, value)) = visitor.next_entry()? { 827 values.insert(key, value); 828 } 829 830 Ok(values.into()) 831 } 832 } 833 834 deserializer.deserialize_any(ValueVisitor) 835 } 836 } 837 838 impl<T> From<T> for Value 839 where 840 T: Into<ValueKind>, 841 { from(value: T) -> Self842 fn from(value: T) -> Self { 843 Self { 844 origin: None, 845 kind: value.into(), 846 } 847 } 848 } 849 850 impl Display for Value { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result851 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 852 write!(f, "{}", self.kind) 853 } 854 } 855 856 #[cfg(test)] 857 mod tests { 858 use super::ValueKind; 859 use crate::Config; 860 use crate::File; 861 use crate::FileFormat; 862 863 #[test] test_i64()864 fn test_i64() { 865 let c = Config::builder() 866 .add_source(File::new("tests/types/i64.toml", FileFormat::Toml)) 867 .build() 868 .unwrap(); 869 870 assert!(std::matches!(c.cache.kind, ValueKind::Table(_))); 871 let v = match c.cache.kind { 872 ValueKind::Table(t) => t, 873 _ => unreachable!(), 874 }; 875 876 let value = v.get("value").unwrap(); 877 assert!( 878 std::matches!(value.kind, ValueKind::I64(120)), 879 "Is not a i64(120): {:?}", 880 value.kind 881 ); 882 } 883 } 884