feat(users/Profpatsch/netencode): add dec::RecordDot
				
					
				
			`dec::RecordDot` accesses a specific field of a netencode record. In order to implement this, either we’d have to introduce a type-level string, but in all honesty this kind of typelevel circlejerking never leads anywhere, so let’s change the trait to use `&self` after all. Usage is pretty much the same, except actually more like you’d expect. Change-Id: I5a7f1a3f587256c50df1b65c2969e5a7194bba70 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2494 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
This commit is contained in:
		
							parent
							
								
									3226e6243f
								
							
						
					
					
						commit
						7d9c30ab3d
					
				
					 2 changed files with 29 additions and 6 deletions
				
			
		|  | @ -601,10 +601,12 @@ pub mod dec { | |||
| 
 | ||||
|     pub trait Decoder<'a> { | ||||
|         type A; | ||||
|         fn dec(u: U<'a>) -> Result<Self::A, DecodeError>; | ||||
|         fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError>; | ||||
|     } | ||||
| 
 | ||||
|     #[derive(Clone, Copy)] | ||||
|     pub struct AnyT; | ||||
|     #[derive(Clone, Copy)] | ||||
|     pub struct AnyU; | ||||
| 
 | ||||
|     // impl Decoder for AnyT {
 | ||||
|  | @ -617,16 +619,17 @@ pub mod dec { | |||
| 
 | ||||
|     impl<'a> Decoder<'a> for AnyU { | ||||
|         type A = U<'a>; | ||||
|         fn dec(u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|         fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|             Ok(u) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[derive(Clone, Copy)] | ||||
|     pub struct ScalarAsBytes; | ||||
| 
 | ||||
|     impl<'a> Decoder<'a> for ScalarAsBytes { | ||||
|         type A = Vec<u8>; | ||||
|         fn dec(u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|         fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|             match u { | ||||
|                 U::N3(u) => Ok(format!("{}", u).into_bytes()), | ||||
|                 U::N6(u) => Ok(format!("{}", u).into_bytes()), | ||||
|  | @ -641,21 +644,41 @@ pub mod dec { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[derive(Clone, Copy)] | ||||
|     pub struct Record<T>(pub T); | ||||
| 
 | ||||
|     impl<'a, Inner: Decoder<'a>> Decoder<'a> for Record<Inner> { | ||||
|         type A = HashMap<&'a str, Inner::A>; | ||||
|         fn dec(u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|         fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|             match u { | ||||
|                 U::Record(map) => | ||||
|                     map.into_iter() | ||||
|                     .map(|(k, v)| Inner::dec(v).map(|v2| (k, v2))) | ||||
|                     .map(|(k, v)| self.0.dec(v).map(|v2| (k, v2))) | ||||
|                     .collect::<Result<Self::A, _>>(), | ||||
|                 o => Err(DecodeError(format!("Cannot decode {:?} into record", o))) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[derive(Clone, Copy)] | ||||
|     pub struct RecordDot<'a, T> { | ||||
|         field: &'a str, | ||||
|         inner: T | ||||
|     } | ||||
| 
 | ||||
|     impl <'a, Inner: Decoder<'a> + Copy> Decoder<'a> for RecordDot<'_, Inner> { | ||||
|         type A = Inner::A; | ||||
|         fn dec(&self, u: U<'a>) -> Result<Self::A, DecodeError> { | ||||
|             match Record(self.inner).dec(u) { | ||||
|                 Ok(mut map) => match map.remove(self.field) { | ||||
|                     Some(inner) => Ok(inner), | ||||
|                     None => Err(DecodeError(format!("Cannot find `{}` in record map", self.field))), | ||||
|                 }, | ||||
|                 Err(err) => Err(err), | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn dec_u(b: &[u8]) -> Result<U, DecodeError> { | ||||
|         match parse::u_u(b) { | ||||
|             Ok((b"", u)) => Ok(u), | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue