1use crate::internal::*;
2use std::ops;
3
4const START: Ident = Ident::Named("start");
5const END: Ident = Ident::Named("end");
6const BOUND: Ident = Ident::Named("bound");
7
8impl<T: FromArgs> FromArgs for ops::Range<T> {
9 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
10 Ok(args.parse(START)?..args.parse(END)?)
11 }
12}
13
14impl<T: FromArgs> FromArgs for ops::RangeFrom<T> {
15 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
16 Ok(args.parse(START)?..)
17 }
18}
19
20impl<T: FromArgs> FromArgs for ops::RangeTo<T> {
21 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
22 Ok(..args.parse(END)?)
23 }
24}
25
26impl FromArgs for ops::RangeFull {
27 fn from_args<S: Source + ?Sized>(_: &mut Args<S>) -> FromArgsResult<Self> {
28 Ok(..)
29 }
30}
31
32impl<T: FromArgs> FromArgs for ops::RangeInclusive<T> {
33 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
34 Ok(args.parse(START)?..=args.parse(END)?)
35 }
36}
37
38impl<T: FromArgs> FromArgs for ops::RangeToInclusive<T> {
39 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
40 Ok(..=args.parse(END)?)
41 }
42}
43
44impl<T: FromArgs> FromArgs for ops::Bound<T> {
45 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
49 args.branch([
50 (".", |_| Ok(Self::Unbounded)),
51 (",", |args| Ok(Self::Excluded(args.parse(BOUND)?))),
52 (",=", |args| Ok(Self::Included(args.parse(BOUND)?))),
53 ])
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Eq, Hash)]
69pub enum RangeDynamic<T> {
70 Range(ops::Range<T>),
71 RangeTo(ops::RangeTo<T>),
72 RangeFrom(ops::RangeFrom<T>),
73 RangeFull(ops::RangeFull),
74 RangeInclusive(ops::RangeInclusive<T>),
75 RangeToInclusive(ops::RangeToInclusive<T>),
76}
77
78impl<T: FromArgs> FromArgs for RangeDynamic<T> {
79 fn from_args<S: Source + ?Sized>(args: &mut Args<S>) -> FromArgsResult<Self> {
80 args.branch([
81 (",,", |args| Ok(Self::Range(from_args(args)?))),
82 (",.", |args| Ok(Self::RangeFrom(from_args(args)?))),
83 (".,", |args| Ok(Self::RangeTo(from_args(args)?))),
84 ("..", |args| Ok(Self::RangeFull(from_args(args)?))),
85 (",,=", |args| Ok(Self::RangeInclusive(from_args(args)?))),
86 (".,=", |args| Ok(Self::RangeToInclusive(from_args(args)?))),
87 ])
88 }
89}
90
91impl<T> ops::RangeBounds<T> for RangeDynamic<T> {
92 fn start_bound(&self) -> ops::Bound<&T> {
93 match self {
94 Self::Range(range) => range.start_bound(),
95 Self::RangeTo(range) => range.start_bound(),
96 Self::RangeFrom(range) => range.start_bound(),
97 Self::RangeFull(range) => range.start_bound(),
98 Self::RangeInclusive(range) => range.start_bound(),
99 Self::RangeToInclusive(range) => range.start_bound(),
100 }
101 }
102
103 fn end_bound(&self) -> ops::Bound<&T> {
104 match self {
105 Self::Range(range) => range.end_bound(),
106 Self::RangeTo(range) => range.end_bound(),
107 Self::RangeFrom(range) => range.end_bound(),
108 Self::RangeFull(range) => range.end_bound(),
109 Self::RangeInclusive(range) => range.end_bound(),
110 Self::RangeToInclusive(range) => range.end_bound(),
111 }
112 }
113}