lexpr/value/
mod.rs

1//! The Value enum, a dynamically typed way of representing any valid S-expression value.
2//!
3//! # Constructing S-Expressions
4//!
5//! Lexpr provides a [`sexp!` macro][macro] to build `lexpr::Value`
6//! objects with very natural S-expression syntax.
7//!
8//! ```
9//! use lexpr::sexp;
10//!
11//! // The type of `john` is `lexpr::Value`
12//! let john = sexp!((
13//!     (name . "John Doe")
14//!     (age . 43)
15//!     (phones "+44 1234567" "+44 2345678")
16//! ));
17//!
18//! println!("first phone number: {}", john["phones"][0]);
19//!
20//! // Convert to a string of S-expression data and print it out
21//! println!("{}", john.to_string());
22//! ```
23//!
24//! The `Value::to_string()` function converts a `lexpr::Value` into a
25//! `String` of S-expression text.
26//!
27//! One neat thing about the `sexp!` macro is that variables and
28//! expressions can be interpolated directly into the S-expression
29//! value as you are building it. The macro will check at compile time
30//! that the value you are interpolating is able to be represented as
31//! S-expression data.
32//!
33//! To interpolate, use the comma (`,`, also known as "unqote" in
34//! Lisp). The interpolated expression must either be a single token,
35//! or surrounded by round or curly braces.
36//!
37//! ```
38//! # use lexpr::sexp;
39//! #
40//! # fn random_phone() -> u16 { 0 }
41//! #
42//! let full_name = "John Doe";
43//! let age_last_year = 42;
44//!
45//! // The type of `john` is `lexpr::Value`
46//! let john = sexp!((
47//!     (name . ,full_name)
48//!     (age . ,(age_last_year + 1))
49//!     (phones ,{ format!("+44 {}", random_phone()) })
50//! ));
51//! ```
52//!
53//! A string of S-expression data can be parsed into a `lexpr::Value` by the
54//! [`lexpr::from_str`][from_str] function. There is also
55//! [`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and
56//! [`from_reader`][from_reader] for parsing from any `io::Read` like a file or
57//! a TCP stream. For all these functions there also is a `_custom` variant
58//! which allows for specifying parser options, in case the input deviates from
59//! the `lexpr` default behavior.
60//!
61//! ```
62//! use lexpr::{sexp, parse::Error, Value};
63//!
64//! # fn main() -> Result<(), Error> {
65//! // Some S-expression input data as a &str. Maybe this comes from the user.
66//! let data = r#"(
67//!         (name . "John Doe")
68//!         (age . 43)
69//!         (phones . (
70//!             "+44 1234567"
71//!             "+44 2345678"
72//!         ))
73//!     )"#;
74//!
75//! // Parse the string of data into lexpr::Value.
76//! let v: Value = lexpr::from_str(data)?;
77//!
78//! // Access parts of the data by indexing with square brackets.
79//! println!("Please call {} at the number {}", v["name"], v["phones"][0]);
80//! # Ok(())
81//! # }
82//! ```
83//!
84//! [macro]: ../macro.sexp.html
85//! [from_str]: ../parse/fn.from_str.html
86//! [from_slice]: ../parse/fn.from_slice.html
87//! [from_reader]: ../parse/fn.from_reader.html
88
89use std::fmt;
90use std::io;
91use std::str;
92
93use crate::cons::{self, Cons};
94use crate::number::Number;
95
96pub use self::index::Index;
97
98/// Represents an S-expression value.
99///
100/// See the [`lexpr::value`] module documentation for usage examples.
101///
102/// [`lexpr::value`]: index.html
103#[derive(Debug, PartialEq, Clone)]
104pub enum Value {
105    /// The special "nil" value.
106    ///
107    /// This is kind of an oddball value. In traditional Lisps (e.g., Common
108    /// Lisp or Emacs Lisp) the empty list can be written as the symbol `nil`,
109    /// while in Scheme, `nil` is just a regular symbol. Furthermore,
110    /// traditional Lisps don't have a separate boolean data type, and represent
111    /// true and false by the symbols `t` and `nil` instead. The `lexpr` parser
112    /// can be instructed to parse the `nil` symbol as the `Nil` value (see
113    /// [`NilSymbol::Special`]), allowing to choose its representation when
114    /// converting to text again (see [`NilSyntax`]). Note that the empty list,
115    /// when written as `()` or implicitly constructed as a list terminator, is
116    /// always parsed as [`Value::Null`], not `Value::Nil`.
117    ///
118    /// In addition to being useful for conversions between S-expression
119    /// variants, this value is also potentially returned when using the square
120    /// bracket indexing operator on `Value`.
121    ///
122    /// [`NilSymbol::Special`]: crate::parse::NilSymbol::Special
123    /// [`NilSyntax`]: ../print/enum.NilSyntax.html
124    Nil,
125
126    /// The empty list.
127    ///
128    /// This value terminates a chain of cons cells forming a proper list.
129    Null,
130
131    /// A boolean value.
132    Bool(bool),
133
134    /// A number.
135    Number(Number),
136
137    /// A character.
138    Char(char),
139
140    /// A string.
141    String(Box<str>),
142
143    /// A symbol.
144    Symbol(Box<str>),
145
146    /// A keyword.
147    Keyword(Box<str>),
148
149    /// A byte vector.
150    Bytes(Box<[u8]>),
151
152    /// Represents a Lisp "cons cell".
153    ///
154    /// Cons cells are often used to form singly-linked lists.
155    /// ```
156    /// # use lexpr::sexp;
157    /// let v = sexp!((a list 1 2 3));
158    /// assert!(v.is_cons());
159    /// assert_eq!(v[4], sexp!(3));
160    /// ```
161    Cons(Cons),
162
163    /// A Lisp vector.
164    Vector(Box<[Value]>),
165}
166
167impl Value {
168    /// Construct a symbol, given its name.
169    pub fn symbol(name: impl Into<Box<str>>) -> Self {
170        Value::Symbol(name.into())
171    }
172
173    /// Construct a keyword, given its name.
174    ///
175    /// ```
176    /// # use lexpr::Value;
177    /// let value = Value::keyword("foo");
178    /// assert!(value.is_keyword());
179    /// assert_eq!(value.as_keyword().unwrap(), "foo");
180    /// ```
181    pub fn keyword(name: impl Into<Box<str>>) -> Self {
182        Value::Keyword(name.into())
183    }
184
185    /// Construct a string.
186    ///
187    /// ```
188    /// # use lexpr::Value;
189    /// let value = Value::string("foo");
190    /// assert!(value.is_string());
191    /// assert_eq!(value.as_str().unwrap(), "foo");
192    /// ```
193    pub fn string(s: impl Into<Box<str>>) -> Self {
194        Value::String(s.into())
195    }
196
197    /// Construct a byte vector.
198    ///
199    /// ```
200    /// # use lexpr::Value;
201    /// let value = Value::bytes(b"foo" as &[u8]);
202    /// assert!(value.is_bytes());
203    /// assert_eq!(value.as_bytes().unwrap(), b"foo");
204    /// ```
205    pub fn bytes(bv: impl Into<Box<[u8]>>) -> Self {
206        Value::Bytes(bv.into())
207    }
208
209    /// Create a cons cell given its `car` and `cdr` fields.
210    ///
211    /// ```
212    /// # use lexpr::Value;
213    /// let value = Value::cons(1, Value::Null);
214    /// assert!(value.is_cons());
215    /// assert_eq!(value.as_pair().unwrap(), (&Value::from(1), &Value::Null));
216    /// ```
217    ///
218    /// Note that you can also construct a cons cell from a Rust pair via the
219    /// `From` trait:
220    ///
221    /// ```
222    /// # use lexpr::Value;
223    /// let value = Value::from((42, "answer"));
224    /// assert!(value.is_cons());
225    /// assert_eq!(value.as_pair().unwrap(), (&Value::from(42), &Value::string("answer")));
226    /// ```
227    pub fn cons<T, U>(car: T, cdr: U) -> Self
228    where
229        T: Into<Value>,
230        U: Into<Value>,
231    {
232        Value::Cons(Cons::new(car, cdr))
233    }
234
235    /// Create a list value from elements convertible into `Value`.
236    ///
237    /// ```
238    /// # use lexpr::{sexp, Value};
239    /// assert_eq!(Value::list(vec![1, 2, 3]), sexp!((1 2 3)));
240    /// ```
241    pub fn list<I>(elements: I) -> Self
242    where
243        I: IntoIterator,
244        I::Item: Into<Value>,
245    {
246        Self::append(elements, Value::Null)
247    }
248
249    /// Returns true if the value is a (proper) list.
250    pub fn is_list(&self) -> bool {
251        match self {
252            Value::Null => true,
253            Value::Cons(pair) => pair
254                .iter()
255                .all(|p| matches!(p.cdr(), Value::Null | Value::Cons(_))),
256            _ => false,
257        }
258    }
259
260    /// Returns true if the value is a dotted (improper) list.
261    ///
262    /// Note that all values that are not pairs are considered dotted lists.
263    ///
264    /// ```
265    /// # use lexpr::{sexp, Value};
266    /// let list = sexp!((1 2 3));
267    /// assert!(!list.is_dotted_list());
268    /// let dotted = sexp!((1 2 . 3));
269    /// assert!(dotted.is_dotted_list());
270    /// ```
271    pub fn is_dotted_list(&self) -> bool {
272        match self {
273            Value::Null => false,
274            Value::Cons(pair) => pair.iter().all(|p| !matches!(p.cdr(), Value::Null)),
275            _ => true,
276        }
277    }
278
279    /// Create a list value from elements convertible into `Value`, using a
280    /// given value as a tail.
281    ///
282    /// ```
283    /// # use lexpr::{sexp, Value};
284    /// assert_eq!(Value::append(vec![1u32, 2], 3), sexp!((1 2 . 3)));
285    /// assert_eq!(Value::append(vec![1u32, 2, 3], sexp!((4 5))), sexp!((1 2 3 4 5)));
286    /// ```
287    pub fn append<I, T>(elements: I, tail: T) -> Self
288    where
289        I: IntoIterator,
290        I::Item: Into<Value>,
291        T: Into<Value>,
292    {
293        let mut list = Cons::new(Value::Nil, Value::Null);
294        let mut pair = &mut list;
295        let mut have_value = false;
296        for item in elements {
297            if have_value {
298                pair.set_cdr(Value::from((Value::Nil, Value::Null)));
299                pair = pair.cdr_mut().as_cons_mut().unwrap();
300            }
301            pair.set_car(item.into());
302            have_value = true;
303        }
304        if have_value {
305            pair.set_cdr(tail.into());
306            Value::Cons(list)
307        } else {
308            tail.into()
309        }
310    }
311
312    /// Create a vector value from elements convertible into `Value`.
313    ///
314    /// ```
315    /// # use lexpr::{sexp, Value};
316    /// assert_eq!(Value::vector(vec![1u32, 2, 3]), sexp!(#(1 2 3)));
317    /// ```
318    pub fn vector<I>(elements: I) -> Self
319    where
320        I: IntoIterator,
321        I::Item: Into<Value>,
322    {
323        let v: Vec<_> = elements.into_iter().map(Into::into).collect();
324        Value::Vector(v.into_boxed_slice())
325    }
326
327    /// Returns true if the value is a String. Returns false otherwise.
328    ///
329    /// For any Value on which `is_string` returns true, `as_str` is guaranteed
330    /// to return the string slice.
331    ///
332    /// ```
333    /// # use lexpr::sexp;
334    /// #
335    /// let v = sexp!(((a . "some string") (b . #f)));
336    ///
337    /// assert!(v["a"].is_string());
338    ///
339    /// // The boolean `false` is not a string.
340    /// assert!(!v["b"].is_string());
341    /// ```
342    pub fn is_string(&self) -> bool {
343        self.as_str().is_some()
344    }
345
346    /// If the value is a String, returns the associated str. Returns `None`
347    /// otherwise.
348    ///
349    /// ```
350    /// # use lexpr::sexp;
351    /// #
352    /// let v = sexp!(((a . "some string") (b . #f)));
353    ///
354    /// assert_eq!(v["a"].as_str(), Some("some string"));
355    ///
356    /// // The boolean `false` is not a string.
357    /// assert_eq!(v["b"].as_str(), None);
358    ///
359    /// // S-expression values are printed in S-expression
360    /// // representation, so strings are in quotes.
361    /// //    The value is: "some string"
362    /// println!("The value is: {}", v["a"]);
363    ///
364    /// // Rust strings are printed without quotes.
365    /// //
366    /// //    The value is: some string
367    /// println!("The value is: {}", v["a"].as_str().unwrap());
368    /// ```
369    pub fn as_str(&self) -> Option<&str> {
370        match self {
371            Value::String(s) => Some(s),
372            _ => None,
373        }
374    }
375
376    /// Returns true if the value is a symbol. Returns false otherwise.
377    ///
378    /// For any Value on which `is_symbol` returns true, `as_symbol` is guaranteed
379    /// to return the string slice.
380    ///
381    /// ```
382    /// # use lexpr::sexp;
383    /// #
384    /// let v = sexp!((#:foo bar "baz"));
385    ///
386    /// assert!(v[1].is_symbol());
387    ///
388    /// // Keywords and strings are not symbols.
389    /// assert!(!v[0].is_symbol());
390    /// assert!(!v[2].is_symbol());
391    /// ```
392    pub fn is_symbol(&self) -> bool {
393        self.as_symbol().is_some()
394    }
395
396    /// If the value is a symbol, returns the associated str. Returns `None`
397    /// otherwise.
398    ///
399    /// ```
400    /// # use lexpr::sexp;
401    /// #
402    /// let v = sexp!(foo);
403    ///
404    /// assert_eq!(v.as_symbol(), Some("foo"));
405    /// ```
406    pub fn as_symbol(&self) -> Option<&str> {
407        match self {
408            Value::Symbol(s) => Some(s),
409            _ => None,
410        }
411    }
412
413    /// Returns true if the value is a keyword. Returns false otherwise.
414    ///
415    /// For any Value on which `is_keyword` returns true, `as_keyword` is guaranteed
416    /// to return the string slice.
417    ///
418    /// ```
419    /// # use lexpr::sexp;
420    /// #
421    /// let v = sexp!((#:foo bar "baz"));
422    ///
423    /// assert!(v[0].is_keyword());
424    ///
425    /// // Symbols and strings are not keywords.
426    /// assert!(!v[1].is_keyword());
427    /// assert!(!v[2].is_keyword());
428    /// ```
429    pub fn is_keyword(&self) -> bool {
430        self.as_keyword().is_some()
431    }
432
433    /// If the value is a keyword, returns the associated str. Returns `None`
434    /// otherwise.
435    ///
436    /// ```
437    /// # use lexpr::sexp;
438    /// #
439    /// let v = sexp!(#:foo);
440    ///
441    /// assert_eq!(v.as_keyword(), Some("foo"));
442    /// ```
443    pub fn as_keyword(&self) -> Option<&str> {
444        match self {
445            Value::Keyword(s) => Some(s),
446            _ => None,
447        }
448    }
449
450    /// Get the name of a symbol or keyword, or the value of a string.
451    ///
452    /// This is useful if symbols, keywords and strings need to be treated
453    /// equivalently in some context.
454    ///
455    /// ```
456    /// # use lexpr::sexp;
457    /// #
458    /// let kw = sexp!(#:foo);
459    /// assert_eq!(kw.as_name(), Some("foo"));
460    ///
461    /// let sym = sexp!(bar);
462    /// assert_eq!(sym.as_name(), Some("bar"));
463    ///
464    /// let s = sexp!("baz");
465    /// assert_eq!(s.as_name(), Some("baz"));
466    /// ```
467    pub fn as_name(&self) -> Option<&str> {
468        match self {
469            Value::Symbol(s) => Some(s),
470            Value::Keyword(s) => Some(s),
471            Value::String(s) => Some(s),
472            _ => None,
473        }
474    }
475
476    /// Returns true if the value is a byte vector. Returns false otherwise.
477    ///
478    /// For any Value on which `is_bytes` returns true, `as_bytes` is guaranteed
479    /// to return the byte slice.
480    ///
481    /// ```
482    /// # use lexpr::sexp;
483    /// #
484    /// let v = sexp!(((a . ,(b"some bytes" as &[u8])) (b . "string")));
485    ///
486    /// assert!(v["a"].is_bytes());
487    ///
488    /// // A string is not a byte vector.
489    /// assert!(!v["b"].is_bytes());
490    /// ```
491    pub fn is_bytes(&self) -> bool {
492        self.as_bytes().is_some()
493    }
494
495    /// If the value is a byte vector, returns the associated byte
496    /// slice. Returns `None` otherwise.
497    ///
498    /// ```
499    /// # use lexpr::sexp;
500    /// #
501    /// let v = sexp!(((a . ,(b"some bytes" as &[u8])) (b . "string")));
502    ///
503    /// assert_eq!(v["a"].as_bytes(), Some(b"some bytes" as &[u8]));
504    ///
505    /// // A string is not a byte vector.
506    /// assert_eq!(v["b"].as_bytes(), None);
507    /// ```
508    pub fn as_bytes(&self) -> Option<&[u8]> {
509        match self {
510            Value::Bytes(s) => Some(s),
511            _ => None,
512        }
513    }
514
515    /// Return `true` if the value is a number.
516    pub fn is_number(&self) -> bool {
517        self.as_number().is_some()
518    }
519
520    /// For numbers, return a reference to them. For other values, return
521    /// `None`.
522    pub fn as_number(&self) -> Option<&Number> {
523        match self {
524            Value::Number(n) => Some(n),
525            _ => None,
526        }
527    }
528
529    /// Returns true if the value is an integer between `i64::MIN` and
530    /// `i64::MAX`.
531    ///
532    /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
533    /// return the integer value.
534    ///
535    /// ```
536    /// # use lexpr::sexp;
537    /// #
538    /// let big = i64::max_value() as u64 + 10;
539    /// let v = sexp!(((a . 64) (b . ,big) (c . 256.0)));
540    ///
541    /// assert!(v["a"].is_i64());
542    ///
543    /// // Greater than i64::MAX.
544    /// assert!(!v["b"].is_i64());
545    ///
546    /// // Numbers with a decimal point are not considered integers.
547    /// assert!(!v["c"].is_i64());
548    /// ```
549    pub fn is_i64(&self) -> bool {
550        match self.as_number() {
551            Some(n) => n.is_i64(),
552            _ => false,
553        }
554    }
555
556    /// Returns true if the value is an integer between zero and `u64::MAX`.
557    ///
558    /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
559    /// return the integer value.
560    ///
561    /// ```
562    /// # use lexpr::sexp;
563    /// #
564    /// let v = sexp!(((a . 64) (b . -64) (c . 256.0)));
565    ///
566    /// assert!(v["a"].is_u64());
567    ///
568    /// // Negative integer.
569    /// assert!(!v["b"].is_u64());
570    ///
571    /// // Numbers with a decimal point are not considered integers.
572    /// assert!(!v["c"].is_u64());
573    /// ```
574    pub fn is_u64(&self) -> bool {
575        match self.as_number() {
576            Some(n) => n.is_u64(),
577            _ => false,
578        }
579    }
580
581    /// Returns true if the value is a number that can be represented by f64.
582    ///
583    /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
584    /// return the floating point value.
585    ///
586    /// Currently this function returns true if and only if both `is_i64` and
587    /// `is_u64` return false but this is not a guarantee in the future.
588    ///
589    /// ```
590    /// # use lexpr::sexp;
591    /// #
592    /// let v = sexp!(((a . 256.0) (b . 64) (c . -64)));
593    ///
594    /// assert!(v["a"].is_f64());
595    ///
596    /// // Integers.
597    /// assert!(!v["b"].is_f64());
598    /// assert!(!v["c"].is_f64());
599    /// ```
600    #[inline]
601    pub fn is_f64(&self) -> bool {
602        match self.as_number() {
603            Some(n) => n.is_f64(),
604            _ => false,
605        }
606    }
607
608    /// If the value is an integer, represent it as i64 if possible. Returns
609    /// None otherwise.
610    ///
611    /// ```
612    /// # use lexpr::sexp;
613    /// #
614    /// let big = i64::max_value() as u64 + 10;
615    /// let v = sexp!(((a . 64) (b . ,big) (c . 256.0)));
616    ///
617    /// assert_eq!(v["a"].as_i64(), Some(64));
618    /// assert_eq!(v["b"].as_i64(), None);
619    /// assert_eq!(v["c"].as_i64(), None);
620    /// ```
621    #[inline]
622    pub fn as_i64(&self) -> Option<i64> {
623        self.as_number().and_then(Number::as_i64)
624    }
625
626    /// If the value is an integer, represent it as u64 if possible. Returns
627    /// None otherwise.
628    ///
629    /// ```
630    /// # use lexpr::sexp;
631    /// #
632    /// let v = sexp!(((a . 64) (b . -64) (c . 256.0)));
633    ///
634    /// assert_eq!(v["a"].as_u64(), Some(64));
635    /// assert_eq!(v["b"].as_u64(), None);
636    /// assert_eq!(v["c"].as_u64(), None);
637    /// ```
638    pub fn as_u64(&self) -> Option<u64> {
639        self.as_number().and_then(Number::as_u64)
640    }
641
642    /// If the value is a number, represent it as f64 if possible. Returns
643    /// None otherwise.
644    ///
645    /// ```
646    /// # use lexpr::sexp;
647    /// #
648    /// let v = sexp!(((a . 256.0) (b . 64) (c . -64)));
649    ///
650    /// assert_eq!(v["a"].as_f64(), Some(256.0));
651    /// assert_eq!(v["b"].as_f64(), Some(64.0));
652    /// assert_eq!(v["c"].as_f64(), Some(-64.0));
653    /// ```
654    pub fn as_f64(&self) -> Option<f64> {
655        self.as_number().and_then(Number::as_f64)
656    }
657
658    /// Returns true if the value is a Boolean. Returns false otherwise.
659    ///
660    /// For any Value on which `is_boolean` returns true, `as_bool` is
661    /// guaranteed to return the boolean value.
662    ///
663    /// ```
664    /// # use lexpr::sexp;
665    /// #
666    /// let v = sexp!(((a . #f) (b . #nil)));
667    ///
668    /// assert!(v["a"].is_boolean());
669    ///
670    /// // The nil value is special, and not a boolean.
671    /// assert!(!v["b"].is_boolean());
672    /// ```
673    pub fn is_boolean(&self) -> bool {
674        self.as_bool().is_some()
675    }
676
677    /// If the value is a `Boolean`, returns the associated bool. Returns None
678    /// otherwise.
679    ///
680    /// ```
681    /// # use lexpr::sexp;
682    /// #
683    /// let v = sexp!(((a . #f) (b . "false")));
684    ///
685    /// assert_eq!(v["a"].as_bool(), Some(false));
686    ///
687    /// // The string `"false"` is a string, not a boolean.
688    /// assert_eq!(v["b"].as_bool(), None);
689    /// ```
690    pub fn as_bool(&self) -> Option<bool> {
691        match self {
692            Value::Bool(b) => Some(*b),
693            _ => None,
694        }
695    }
696
697    /// Returns true if the value is a character. Returns false otherwise.
698    pub fn is_char(&self) -> bool {
699        self.as_char().is_some()
700    }
701
702    /// If the value is a character, returns the associated `char`. Returns None
703    /// otherwise.
704    ///
705    /// ```
706    /// # use lexpr::sexp;
707    /// #
708    /// let v = sexp!(((a . 'c') (b . "c")));
709    ///
710    /// assert_eq!(v["a"].as_char(), Some('c'));
711    ///
712    /// // The string `"c"` is a single-character string, not a character.
713    /// assert_eq!(v["b"].as_char(), None);
714    /// ```
715    pub fn as_char(&self) -> Option<char> {
716        match self {
717            Value::Char(c) => Some(*c),
718            _ => None,
719        }
720    }
721
722    /// Returns true if the value is `Nil`. Returns false otherwise.
723    ///
724    /// For any Value on which `is_nil` returns true, `as_nil` is guaranteed
725    /// to return `Some(())`.
726    ///
727    /// ```
728    /// # use lexpr::sexp;
729    /// #
730    /// let v = sexp!(((a . #nil) (b . #f)));
731    ///
732    /// assert!(v["a"].is_nil());
733    ///
734    /// // The boolean `false` is not nil.
735    /// assert!(!v["b"].is_nil());
736    /// ```
737    pub fn is_nil(&self) -> bool {
738        self.as_nil().is_some()
739    }
740
741    /// If the value is `Nil`, returns `()`. Returns `None` otherwise.
742    ///
743    /// ```
744    /// # use lexpr::sexp;
745    /// #
746    /// let v = sexp!(((a . #nil) (b . #f) (c . ())));
747    ///
748    /// assert_eq!(v["a"].as_nil(), Some(()));
749    ///
750    /// // The boolean `false` is not nil.
751    /// assert_eq!(v["b"].as_nil(), None);
752    /// // Neither is the empty list.
753    /// assert_eq!(v["c"].as_nil(), None);
754    /// ```
755    pub fn as_nil(&self) -> Option<()> {
756        match self {
757            Value::Nil => Some(()),
758            _ => None,
759        }
760    }
761
762    /// Returns true if the value is `Null`. Returns false otherwise.
763    pub fn is_null(&self) -> bool {
764        self.as_null().is_some()
765    }
766
767    /// If the value is `Null`, returns `()`. Returns `None` otherwise.
768    pub fn as_null(&self) -> Option<()> {
769        match self {
770            Value::Null => Some(()),
771            _ => None,
772        }
773    }
774
775    /// Returns true if the value is a cons cell. Returns `False` otherwise.
776    pub fn is_cons(&self) -> bool {
777        matches!(self, Value::Cons(_))
778    }
779
780    /// If the value is a cons cell, returns a reference to it. Returns `None`
781    /// otherwise.
782    pub fn as_cons(&self) -> Option<&Cons> {
783        match self {
784            Value::Cons(pair) => Some(pair),
785            _ => None,
786        }
787    }
788
789    /// If the value is a cons cell, returns a mutable reference to it. Returns
790    /// `None` otherwise.
791    pub fn as_cons_mut(&mut self) -> Option<&mut Cons> {
792        match self {
793            Value::Cons(pair) => Some(pair),
794            _ => None,
795        }
796    }
797
798    /// If the value is a cons cell, return references to its `car` and `cdr`
799    /// fields.
800    ///
801    /// ```
802    /// # use lexpr::sexp;
803    /// let cell = sexp!((foo . bar));
804    /// assert_eq!(cell.as_pair(), Some((&sexp!(foo), &sexp!(bar))));
805    /// assert_eq!(sexp!("not-a-pair").as_pair(), None);
806    /// ```
807    pub fn as_pair(&self) -> Option<(&Value, &Value)> {
808        self.as_cons().map(Cons::as_pair)
809    }
810
811    /// Returns true if the value is a vector.
812    pub fn is_vector(&self) -> bool {
813        matches!(self, Value::Vector(_))
814    }
815
816    /// If the value is a vector, return a reference to its elements.
817    ///
818    /// ```
819    /// # use lexpr::{sexp, Value};
820    /// let v = sexp!(#(1 2 "three"));
821    /// let slice: &[Value] = &[sexp!(1), sexp!(2), sexp!("three")];
822    /// assert_eq!(v.as_slice(), Some(slice));
823    /// ```
824    pub fn as_slice(&self) -> Option<&[Value]> {
825        match self {
826            Value::Vector(elements) => Some(elements),
827            _ => None,
828        }
829    }
830
831    /// If the value is a vector, return a mutable reference to its elements.
832    ///
833    /// ```
834    /// # use lexpr::{sexp, Value};
835    /// let mut v = sexp!(#(1 2 "three"));
836    /// v.as_slice_mut().unwrap()[2] = sexp!(3);
837    /// let slice: &[Value] = &[sexp!(1), sexp!(2), sexp!(3)];
838    /// assert_eq!(v.as_slice(), Some(slice));
839    /// ```
840    pub fn as_slice_mut(&mut self) -> Option<&mut [Value]> {
841        match self {
842            Value::Vector(elements) => Some(elements),
843            _ => None,
844        }
845    }
846
847    /// If the value is a list, return an iterator over the list elements.
848    ///
849    /// If the value is not either a cons cell or `Null`, `None` is returned.
850    ////
851    /// Note that the returned iterator has special behavior for improper lists, yielding the
852    /// element after the dot after returning `None` the first time.
853    ///
854    /// ```
855    /// use lexpr::sexp;
856    ///
857    /// let value = lexpr::from_str("(1 2 . 3)").unwrap();
858    /// let mut iter = value.list_iter().unwrap();
859    /// assert_eq!(iter.next(), Some(&sexp!(1)));
860    /// assert_eq!(iter.next(), Some(&sexp!(2)));
861    /// assert_eq!(iter.next(), None);
862    /// assert_eq!(iter.next(), Some(&sexp!(3)));
863    /// assert_eq!(iter.next(), None);
864    /// ```
865    pub fn list_iter(&self) -> Option<cons::ListIter<'_>> {
866        match self {
867            Value::Cons(cell) => Some(cons::ListIter::cons(cell)),
868            Value::Null => Some(cons::ListIter::empty()),
869            _ => None,
870        }
871    }
872
873    /// Attempts conversion to a vector, cloning the values.
874    ///
875    /// For proper lists (including `Value::Null`), this returns a vector of
876    /// values. If you want to handle improper list in a similar way, combine
877    /// [`as_cons`] and the [`Cons::to_vec`] method.
878    ///
879    /// ```
880    /// # use lexpr::{sexp, Value};
881    /// assert_eq!(sexp!((1 2 3)).to_vec(), Some(vec![sexp!(1), sexp!(2), sexp!(3)]));
882    /// assert_eq!(sexp!(()).to_vec(), Some(vec![]));
883    /// assert_eq!(sexp!((1 2 . 3)).to_vec(), None);
884    /// ```
885    /// [`as_cons`]: Value::as_cons
886    pub fn to_vec(&self) -> Option<Vec<Value>> {
887        match self {
888            Value::Null => Some(Vec::new()),
889            Value::Cons(pair) => {
890                let (vec, rest) = pair.to_ref_vec();
891                if rest.is_null() {
892                    Some(vec.into_iter().cloned().collect())
893                } else {
894                    None
895                }
896            }
897            _ => None,
898        }
899    }
900
901    /// Attempts conversion to a vector, taking references to the values.
902    ///
903    /// For proper lists (including `Value::Null`), this returns a vector of
904    /// value references. If you want to handle improper list in a similar way,
905    /// combine [`as_cons`] and the [`Cons::to_ref_vec`] method.
906    ///
907    /// ```
908    /// # use lexpr::{sexp, Value};
909    /// assert_eq!(sexp!((1 2 3)).to_ref_vec(), Some(vec![&sexp!(1), &sexp!(2), &sexp!(3)]));
910    /// assert_eq!(sexp!(()).to_ref_vec(), Some(vec![]));
911    /// assert_eq!(sexp!((1 2 . 3)).to_ref_vec(), None);
912    /// ```
913    ///
914    /// [`as_cons`]: Value::as_cons
915    pub fn to_ref_vec(&self) -> Option<Vec<&Value>> {
916        match self {
917            Value::Null => Some(Vec::new()),
918            Value::Cons(pair) => {
919                let (vec, rest) = pair.to_ref_vec();
920                if rest.is_null() {
921                    Some(vec)
922                } else {
923                    None
924                }
925            }
926            _ => None,
927        }
928    }
929
930    /// Index into a S-expression list. A string or `Value` value can
931    /// be used to access a value in an association list, and a usize
932    /// index can be used to access the n-th element of a list.
933    ///
934    /// For indexing into association lists, the given string will
935    /// match strings, symbols and keywords.
936    ///
937    /// Returns `None` if the type of `self` does not match the type
938    /// of the index, for example if the index is a string and `self`
939    /// is not an association list. Also returns `None` if the given
940    /// key does not exist in the map or the given index is not within
941    /// the bounds of the list; note that the tail of an improper list
942    /// is also considered out-of-bounds.
943    ///
944    /// In Scheme terms, this method can be thought of a combination
945    /// of `assoc-ref` and `list-ref`, depending on the argument type. If
946    /// you want to look up a number in an association list, use an
947    /// `Value` value containing that number.
948    ///
949    /// ```
950    /// # use lexpr::sexp;
951    /// #
952    /// let alist = sexp!((("A" . 65) (B . 66) (#:C . 67) (42 . "The answer")));
953    /// assert_eq!(alist.get("A").unwrap(), &sexp!(65));
954    /// assert_eq!(alist.get("B").unwrap(), &sexp!(66));
955    /// assert_eq!(alist.get("C").unwrap(), &sexp!(67));
956    /// assert_eq!(alist.get(sexp!(42)).unwrap(), &sexp!("The answer"));
957    ///
958    /// let list = sexp!(("A" "B" "C"));
959    /// assert_eq!(*list.get(2).unwrap(), sexp!("C"));
960    ///
961    /// assert_eq!(list.get("A"), None);
962    /// ```
963    ///
964    /// Square brackets can also be used to index into a value in a
965    /// more concise way. This returns the nil value in cases where
966    /// `get` would have returned `None`. See [`Index`] for details.
967    ///
968    /// ```
969    /// # use lexpr::sexp;
970    /// #
971    /// let alist = sexp!((
972    ///     ("A" . ("a" "á" "à"))
973    ///     ("B" . ((b . 42) (c . 23)))
974    ///     ("C" . ("c" "ć" "ć̣" "ḉ"))
975    /// ));
976    /// assert_eq!(alist["B"][0], sexp!((b . 42)));
977    /// assert_eq!(alist["C"][1], sexp!("ć"));
978    ///
979    /// assert_eq!(alist["D"], sexp!(#nil));
980    /// assert_eq!(alist[0]["x"]["y"]["z"], sexp!(#nil));
981    /// ```
982    ///
983    /// [`Index`]: trait.Index.html
984    pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
985        index.index_into(self)
986    }
987}
988
989struct WriterFormatter<'a, 'b> {
990    inner: &'a mut fmt::Formatter<'b>,
991}
992
993impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
994    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
995        fn io_error<E>(_: E) -> io::Error {
996            // Sexp does not matter because fmt::Debug and fmt::Display impls
997            // below just map it to fmt::Error
998            io::Error::new(io::ErrorKind::Other, "fmt error")
999        }
1000        let s = str::from_utf8(buf).map_err(io_error)?;
1001        self.inner.write_str(s).map_err(io_error)?;
1002        Ok(buf.len())
1003    }
1004
1005    fn flush(&mut self) -> io::Result<()> {
1006        Ok(())
1007    }
1008}
1009
1010impl fmt::Display for Value {
1011    /// Display an S-expression value as a string.
1012    ///
1013    /// ```
1014    /// # use lexpr::sexp;
1015    /// #
1016    /// let value = sexp!(((city "London") (street "10 Downing Street")));
1017    ///
1018    /// // Compact format:
1019    /// //
1020    /// // ((city "London") (street "10 Downing Street"))
1021    /// let compact = format!("{}", value);
1022    /// assert_eq!(compact,
1023    ///     r#"((city "London") (street "10 Downing Street"))"#);
1024    /// ```
1025    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1026        let mut wr = WriterFormatter { inner: f };
1027        crate::print::to_writer(&mut wr, self).map_err(|_| fmt::Error)
1028    }
1029}
1030
1031impl str::FromStr for Value {
1032    /// Parse an S-expression value from a string.
1033    type Err = crate::parse::Error;
1034
1035    fn from_str(s: &str) -> Result<Self, Self::Err> {
1036        crate::parse::from_str(s)
1037    }
1038}
1039
1040mod from;
1041mod index;
1042mod partial_eq;
1043
1044#[cfg(test)]
1045mod tests;