forked from Orchid/orchid
Added support for defining macros in Rust within the macro system
Also fixed a lot of bugs
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::Infallible;
|
||||
use std::future::Future;
|
||||
@@ -5,6 +6,7 @@ use std::iter;
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
use futures::future::join_all;
|
||||
use itertools::Itertools;
|
||||
use never::Never;
|
||||
use regex::Regex;
|
||||
@@ -77,9 +79,12 @@ impl FmtElement {
|
||||
pub fn bounded(i: u32) -> Self { Self::sub(i, Some(true)) }
|
||||
pub fn unbounded(i: u32) -> Self { Self::sub(i, Some(false)) }
|
||||
pub fn last(i: u32) -> Self { Self::sub(i, None) }
|
||||
pub fn sequence(len: usize, bounded: Option<bool>) -> impl Iterator<Item = Self> {
|
||||
let len32: u32 = len.try_into().unwrap();
|
||||
(0..len32 - 1).map(FmtElement::unbounded).chain([FmtElement::sub(len32 - 1, bounded)])
|
||||
pub fn sequence(len: usize, bounded: Option<bool>) -> Vec<Self> {
|
||||
match len.try_into().unwrap() {
|
||||
0u32 => vec![],
|
||||
1u32 => vec![FmtElement::sub(0, bounded)],
|
||||
n => (0..n - 1).map(FmtElement::unbounded).chain([FmtElement::sub(n - 1, bounded)]).collect(),
|
||||
}
|
||||
}
|
||||
pub fn from_api(api: &api::FormattingElement) -> Self {
|
||||
match_mapping!(api, api::FormattingElement => FmtElement {
|
||||
@@ -109,6 +114,13 @@ fn variants_parse_test() {
|
||||
println!("final: {vars:?}")
|
||||
}
|
||||
|
||||
/// Represents a collection of formatting strings for the same set of parameters
|
||||
/// from which the formatter can choose within their associated constraints.
|
||||
///
|
||||
/// - {0b} can be replaced by any variant of the parameter.
|
||||
/// - {0} can only be replaced by a bounded variant of the parameter
|
||||
/// - {0l} causes the current end restriction to be applied to the parameter.
|
||||
/// This is to be used if the parameter is at the very end of the variant.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq, Default)]
|
||||
pub struct Variants(pub Vec<Variant>);
|
||||
impl Variants {
|
||||
@@ -183,19 +195,24 @@ impl Variants {
|
||||
fn add(&mut self, bounded: bool, s: &'_ str) {
|
||||
self.0.push(Variant { bounded, elements: Self::parse(s) })
|
||||
}
|
||||
// This option is available in all positions
|
||||
/// This option is available in all positions.
|
||||
/// See [Variants] for a description of the format strings
|
||||
pub fn bounded(mut self, s: &'_ str) -> Self {
|
||||
self.add(true, s);
|
||||
self
|
||||
}
|
||||
// This option is only available in positions immediately preceding the end of
|
||||
// the sequence or a parenthesized subsequence.
|
||||
/// This option is only available in positions immediately preceding the end
|
||||
/// of the sequence or a parenthesized subsequence.
|
||||
/// See [Variants] for a description of the format strings
|
||||
pub fn unbounded(mut self, s: &'_ str) -> Self {
|
||||
self.add(false, s);
|
||||
self
|
||||
}
|
||||
pub fn sequence(len: usize, delim: &str, seq_bnd: Option<bool>) -> Rc<Self> {
|
||||
let seq = Itertools::intersperse(FmtElement::sequence(len, seq_bnd), FmtElement::str(delim));
|
||||
let seq = Itertools::intersperse(
|
||||
FmtElement::sequence(len, seq_bnd).into_iter(),
|
||||
FmtElement::str(delim),
|
||||
);
|
||||
Rc::new(Variants(vec![Variant { bounded: true, elements: seq.collect_vec() }]))
|
||||
}
|
||||
pub fn units(self: &Rc<Self>, subs: impl IntoIterator<Item = FmtUnit>) -> FmtUnit {
|
||||
@@ -278,3 +295,12 @@ impl Format for Never {
|
||||
|
||||
/// Format with default strategy. Currently equal to [take_first_fmt]
|
||||
pub async fn fmt(v: &(impl Format + ?Sized), i: &Interner) -> String { take_first_fmt(v, i).await }
|
||||
/// Format a sequence with default strategy. Currently equal to [take_first_fmt]
|
||||
pub async fn fmt_v<F: Format + ?Sized, R: Borrow<F>>(
|
||||
v: impl IntoIterator<Item = R>,
|
||||
i: &Interner,
|
||||
) -> impl Iterator<Item = String> {
|
||||
join_all(v.into_iter().map(|f| async move { take_first_fmt(f.borrow(), i).await }))
|
||||
.await
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user