1#![doc(issue_tracker_base_url = "https://github.com/gabrielfalcao/unique-pointer/issues/")]
2use std::fmt::Display;
22use gradient_slice::Gradient as Slicer;
23
24
25#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
38pub struct Gradient<'a> {
39 input: &'a str,
40 slice: Slicer<'a, char>,
41}
42impl<'a> Iterator for Gradient<'a> {
43 type Item = String;
44
45 fn next(&mut self) -> Option<String> {
46 self.slice.next().map(|slice| {
47 slice
48 .iter()
49 .map(Clone::clone)
50 .map(String::from)
51 .collect::<String>()
52 })
53 }
54}
55impl<'a> Gradient<'a> {
56 pub fn input(&self) -> &'a str {
57 self.input
58 }
59}
60impl<'a> Gradient<'a> {
61 pub fn window(&self) -> String {
62 self.slice.window().iter().map(Clone::clone).map(String::from).collect()
63 }
64
65 pub fn finished(&self) -> bool {
66 self.slice.finished()
67 }
68
69 pub fn width(&self) -> usize {
70 self.slice.width()
71 }
72
73 pub fn start(&self) -> usize {
74 self.slice.start()
75 }
76
77 pub fn end(&self) -> usize {
78 self.slice.end()
79 }
80
81 pub fn range(&self) -> core::ops::Range<usize> {
82 self.slice.range()
83 }
84
85 pub fn len(&self) -> usize {
86 self.slice.len()
87 }
88
89 pub fn new<T: Display>(s: T) -> Gradient<'a> {
90 Gradient {
91 input: s.to_string().leak(),
92 slice: Slicer::new(s.to_string().chars().collect::<Vec<char>>()),
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn gradient() {
103 let result = Gradient::new(" abc ").collect::<Vec<String>>();
104 assert_eq!(
105 result,
106 vec![
107 " ", "a", "b", "c", " ", " a", "ab", "bc", "c ", " ab", "abc", "bc ", " abc",
108 "abc ", " abc "
109 ]
110 );
111 }
112 #[test]
113 fn empty() {
114 assert_eq!(
115 Gradient::new("").collect::<Vec<_>>().len(),
116 0
117 );
118 }
119}