99//! [features](#features).
1010//!
1111//! ```
12+ //! # use std::collections::HashMap;
1213//! use interpolator::{format, Formattable};
1314//!
1415//! let formatted = format(
1516//! "{value:+05}", // could be dynamic
16- //! &[("value", Formattable::display(&12))].into_iter().collect(),
17+ //! &[("value", Formattable::display(&12))]
18+ //! .into_iter()
19+ //! .collect::<HashMap<_, _>>(),
1720//! )?;
1821//!
1922//! assert_eq!(formatted, format!("{:+05}", 12));
@@ -55,10 +58,10 @@ use interpolator::{format, Formattable};
5558// reference
5659let items = [&"hello", &"hi", &"hey"].map(Formattable::display);
5760let items = Formattable::iter(&items);
58- let format_str = "Greetings: {items:i..-1(`{}`)(, )} and `{items:i-1}`";
61+ let format_str = "Greetings: {items:i..-1(`{}{outside} `)(, )} and `{items:i-1}{outside }`";
5962assert_eq!(
60- format(format_str, &hash!("items" => items))?,
61- "Greetings: `hello`, `hi` and `hey`"
63+ format(format_str, &hash!("items" => items, "outside" => Formattable::display(&'!') ))?,
64+ "Greetings: `hello! `, `hi! ` and `hey! `"
6265);
6366# return Ok::<(), interpolator::Error>(())
6467```"#
@@ -112,11 +115,14 @@ type Result<T = (), E = Error> = std::result::Result<T, E>;
112115/// string.
113116///
114117/// ```
118+ /// # use std::collections::HashMap;
115119/// use interpolator::{format, Formattable};
116120///
117121/// let formatted = format(
118122/// "{value:+05}", // could be dynamic
119- /// &[("value", Formattable::display(&12))].into_iter().collect(),
123+ /// &[("value", Formattable::display(&12))]
124+ /// .into_iter()
125+ /// .collect::<HashMap<_, _>>(),
120126/// )
121127/// .unwrap();
122128///
@@ -130,28 +136,64 @@ type Result<T = (), E = Error> = std::result::Result<T, E>;
130136/// failed.
131137///
132138/// For more details have a look at [`Error`] and [`ParseError`].
133- pub fn format < K : Borrow < str > + Eq + Hash > (
134- format : & str ,
135- context : & HashMap < K , Formattable > ,
136- ) -> Result < String > {
139+ pub fn format ( format : & str , context : & impl Context ) -> Result < String > {
137140 let mut out = String :: with_capacity ( format. len ( ) ) ;
138141 write ( & mut out, format, context) ?;
139142 Ok ( out)
140143}
141144
145+ /// Context for `format` and `write`
146+ pub trait Context {
147+ /// Returns the [`Formattable`] for the requested key
148+ fn get ( & self , key : & str ) -> Option < Formattable > ;
149+ }
150+
151+ impl < K : Borrow < str > + Eq + Hash > Context for HashMap < K , Formattable < ' _ > > {
152+ fn get ( & self , key : & str ) -> Option < Formattable > {
153+ HashMap :: get ( self , key) . copied ( )
154+ }
155+ }
156+
157+ #[ cfg( feature = "iter" ) ]
158+ struct IterContext < ' a > {
159+ outer : & ' a dyn Context ,
160+ inner : Formattable < ' a > ,
161+ }
162+
163+ #[ cfg( feature = "iter" ) ]
164+ impl < ' a > IterContext < ' a > {
165+ fn new ( outer : & ' a impl Context , inner : Formattable < ' a > ) -> Self {
166+ Self { outer, inner }
167+ }
168+ }
169+
170+ #[ cfg( feature = "iter" ) ]
171+ impl < ' a > Context for IterContext < ' a > {
172+ fn get ( & self , key : & str ) -> Option < Formattable > {
173+ if key. is_empty ( ) {
174+ Some ( self . inner )
175+ } else {
176+ self . outer . get ( key)
177+ }
178+ }
179+ }
180+
142181/// Runtime version of [`write!`].
143182///
144183/// Takes a mutable [`Write`] e.g. `&mut String`, a format string and a context,
145184/// containing [`Formattable`] values.
146185///
147186/// ```
187+ /// # use std::collections::HashMap;
148188/// use interpolator::{write, Formattable};
149189///
150190/// let mut buf = String::new();
151191/// write(
152192/// &mut buf,
153193/// "{value:+05}", // could be dynamic
154- /// &[("value", Formattable::display(&12))].into_iter().collect(),
194+ /// &[("value", Formattable::display(&12))]
195+ /// .into_iter()
196+ /// .collect::<HashMap<_, _>>(),
155197/// )
156198/// .unwrap();
157199///
@@ -165,11 +207,7 @@ pub fn format<K: Borrow<str> + Eq + Hash>(
165207/// failed.
166208///
167209/// For more details have a look at [`Error`] and [`ParseError`].
168- pub fn write < ' a , K : Borrow < str > + Eq + Hash , F : Borrow < Formattable < ' a > > > (
169- out : & mut impl Write ,
170- mut format : & str ,
171- context : & ' a HashMap < K , F > ,
172- ) -> Result {
210+ pub fn write ( out : & mut impl Write , mut format : & str , context : & impl Context ) -> Result {
173211 let format = & mut format;
174212 let idx = & mut 0 ;
175213 while !format. is_empty ( ) {
@@ -206,6 +244,7 @@ pub fn write<'a, K: Borrow<str> + Eq + Hash, F: Borrow<Formattable<'a>>>(
206244 zero,
207245 trait_,
208246 * idx,
247+ context,
209248 ) ?;
210249 ensure ! ( format. starts_with( '}' ) , ParseError :: Expected ( "}" , * idx) ) ;
211250 step ( 1 , format, idx) ;
0 commit comments