| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 1 | use std::slice; |
| 2 | |
| 3 | use super::value::ProtobufValue; |
| 4 | use super::value::ReflectValueRef; |
| Haibo Huang | d32e6ee | 2020-08-12 13:52:04 -0700 | [diff] [blame] | 5 | use crate::repeated::RepeatedField; |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 6 | |
| 7 | pub trait ReflectRepeated: 'static { |
| 8 | fn reflect_iter(&self) -> ReflectRepeatedIter; |
| 9 | fn len(&self) -> usize; |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 10 | fn get(&self, index: usize) -> &dyn ProtobufValue; |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 11 | } |
| 12 | |
| 13 | impl<V: ProtobufValue + 'static> ReflectRepeated for Vec<V> { |
| 14 | fn reflect_iter<'a>(&'a self) -> ReflectRepeatedIter<'a> { |
| 15 | ReflectRepeatedIter { |
| 16 | imp: Box::new(ReflectRepeatedIterImplSlice::<'a, V> { iter: self.iter() }), |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | fn len(&self) -> usize { |
| 21 | Vec::len(self) |
| 22 | } |
| 23 | |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 24 | fn get(&self, index: usize) -> &dyn ProtobufValue { |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 25 | &self[index] |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | // useless |
| 30 | impl<V: ProtobufValue + 'static> ReflectRepeated for [V] { |
| 31 | fn reflect_iter<'a>(&'a self) -> ReflectRepeatedIter<'a> { |
| 32 | ReflectRepeatedIter { |
| 33 | imp: Box::new(ReflectRepeatedIterImplSlice::<'a, V> { iter: self.iter() }), |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | fn len(&self) -> usize { |
| 38 | <[_]>::len(self) |
| 39 | } |
| 40 | |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 41 | fn get(&self, index: usize) -> &dyn ProtobufValue { |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 42 | &self[index] |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | impl<V: ProtobufValue + 'static> ReflectRepeated for RepeatedField<V> { |
| 47 | fn reflect_iter<'a>(&'a self) -> ReflectRepeatedIter<'a> { |
| 48 | ReflectRepeatedIter { |
| 49 | imp: Box::new(ReflectRepeatedIterImplSlice::<'a, V> { iter: self.iter() }), |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | fn len(&self) -> usize { |
| 54 | RepeatedField::len(self) |
| 55 | } |
| 56 | |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 57 | fn get(&self, index: usize) -> &dyn ProtobufValue { |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 58 | &self[index] |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | trait ReflectRepeatedIterTrait<'a> { |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 63 | fn next(&mut self) -> Option<&'a dyn ProtobufValue>; |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 64 | } |
| 65 | |
| 66 | struct ReflectRepeatedIterImplSlice<'a, V: ProtobufValue + 'static> { |
| 67 | iter: slice::Iter<'a, V>, |
| 68 | } |
| 69 | |
| 70 | impl<'a, V: ProtobufValue + 'static> ReflectRepeatedIterTrait<'a> |
| 71 | for ReflectRepeatedIterImplSlice<'a, V> |
| 72 | { |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 73 | fn next(&mut self) -> Option<&'a dyn ProtobufValue> { |
| 74 | self.iter.next().map(|v| v as &dyn ProtobufValue) |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 75 | } |
| 76 | } |
| 77 | |
| 78 | pub struct ReflectRepeatedIter<'a> { |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 79 | imp: Box<dyn ReflectRepeatedIterTrait<'a> + 'a>, |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | impl<'a> Iterator for ReflectRepeatedIter<'a> { |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 83 | type Item = &'a dyn ProtobufValue; |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 84 | |
| 85 | fn next(&mut self) -> Option<Self::Item> { |
| 86 | self.imp.next() |
| 87 | } |
| 88 | } |
| 89 | |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 90 | impl<'a> IntoIterator for &'a dyn ReflectRepeated { |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 91 | type IntoIter = ReflectRepeatedIter<'a>; |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 92 | type Item = &'a dyn ProtobufValue; |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 93 | |
| 94 | fn into_iter(self) -> Self::IntoIter { |
| 95 | self.reflect_iter() |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | pub trait ReflectRepeatedEnum<'a> { |
| 100 | fn len(&self) -> usize; |
| 101 | |
| 102 | fn get(&self, index: usize) -> ReflectValueRef<'a>; |
| 103 | } |
| 104 | |
| 105 | pub trait ReflectRepeatedMessage<'a> { |
| 106 | fn len(&self) -> usize; |
| 107 | |
| 108 | fn get(&self, index: usize) -> ReflectValueRef<'a>; |
| 109 | } |
| 110 | |
| 111 | pub enum ReflectRepeatedRef<'a> { |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 112 | Generic(&'a dyn ReflectRepeated), |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 113 | U32(&'a [u32]), |
| 114 | U64(&'a [u64]), |
| 115 | I32(&'a [i32]), |
| 116 | I64(&'a [i64]), |
| 117 | F32(&'a [f32]), |
| 118 | F64(&'a [f64]), |
| 119 | Bool(&'a [bool]), |
| 120 | String(&'a [String]), |
| 121 | Bytes(&'a [Vec<u8>]), |
| Haibo Huang | 4bf8b46 | 2020-11-24 20:53:50 -0800 | [diff] [blame] | 122 | Enum(Box<dyn ReflectRepeatedEnum<'a> + 'a>), |
| 123 | Message(Box<dyn ReflectRepeatedMessage<'a> + 'a>), |
| Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | impl<'a> ReflectRepeatedRef<'a> { |
| 127 | fn len(&self) -> usize { |
| 128 | match *self { |
| 129 | ReflectRepeatedRef::Generic(ref r) => r.len(), |
| 130 | ReflectRepeatedRef::U32(ref r) => r.len(), |
| 131 | ReflectRepeatedRef::U64(ref r) => r.len(), |
| 132 | ReflectRepeatedRef::I32(ref r) => r.len(), |
| 133 | ReflectRepeatedRef::I64(ref r) => r.len(), |
| 134 | ReflectRepeatedRef::F32(ref r) => r.len(), |
| 135 | ReflectRepeatedRef::F64(ref r) => r.len(), |
| 136 | ReflectRepeatedRef::Bool(ref r) => r.len(), |
| 137 | ReflectRepeatedRef::String(ref r) => r.len(), |
| 138 | ReflectRepeatedRef::Bytes(ref r) => r.len(), |
| 139 | ReflectRepeatedRef::Enum(ref r) => r.len(), |
| 140 | ReflectRepeatedRef::Message(ref r) => r.len(), |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | fn get(&self, index: usize) -> ReflectValueRef<'a> { |
| 145 | match *self { |
| 146 | ReflectRepeatedRef::Generic(ref r) => r.get(index).as_ref(), |
| 147 | ReflectRepeatedRef::U32(ref r) => ReflectValueRef::U32(r[index]), |
| 148 | ReflectRepeatedRef::U64(ref r) => ReflectValueRef::U64(r[index]), |
| 149 | ReflectRepeatedRef::I32(ref r) => ReflectValueRef::I32(r[index]), |
| 150 | ReflectRepeatedRef::I64(ref r) => ReflectValueRef::I64(r[index]), |
| 151 | ReflectRepeatedRef::F32(ref r) => ReflectValueRef::F32(r[index]), |
| 152 | ReflectRepeatedRef::F64(ref r) => ReflectValueRef::F64(r[index]), |
| 153 | ReflectRepeatedRef::Bool(ref r) => ReflectValueRef::Bool(r[index]), |
| 154 | ReflectRepeatedRef::String(ref r) => ReflectValueRef::String(&r[index]), |
| 155 | ReflectRepeatedRef::Bytes(ref r) => ReflectValueRef::Bytes(&r[index]), |
| 156 | ReflectRepeatedRef::Enum(ref r) => r.get(index), |
| 157 | ReflectRepeatedRef::Message(ref r) => r.get(index), |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | pub struct ReflectRepeatedRefIter<'a> { |
| 163 | repeated: &'a ReflectRepeatedRef<'a>, |
| 164 | pos: usize, |
| 165 | } |
| 166 | |
| 167 | impl<'a> Iterator for ReflectRepeatedRefIter<'a> { |
| 168 | type Item = ReflectValueRef<'a>; |
| 169 | |
| 170 | fn next(&mut self) -> Option<Self::Item> { |
| 171 | if self.pos < self.repeated.len() { |
| 172 | let pos = self.pos; |
| 173 | self.pos += 1; |
| 174 | Some(self.repeated.get(pos)) |
| 175 | } else { |
| 176 | None |
| 177 | } |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | impl<'a> IntoIterator for &'a ReflectRepeatedRef<'a> { |
| 182 | type IntoIter = ReflectRepeatedRefIter<'a>; |
| 183 | type Item = ReflectValueRef<'a>; |
| 184 | |
| 185 | fn into_iter(self) -> Self::IntoIter { |
| 186 | ReflectRepeatedRefIter { |
| 187 | repeated: self, |
| 188 | pos: 0, |
| 189 | } |
| 190 | } |
| 191 | } |