alamb commented on pull request #984:
URL: https://github.com/apache/arrow-rs/pull/984#issuecomment-992700643


   
   The other thing I can think of, that seems a bit of a hack, but might be ok 
would be to take something like `impl TryInto<i128>` which covers all current 
native types
   
   ```rust
   
   /// Perform `left == right` operation on an array and a numeric scalar
   /// value. Supports PrimtiveArrays, and DictionaryArrays that have primitive 
values
   pub fn eq_dyn_scalar<T>(
       left: &dyn Array,
       right: T
   ) -> Result<BooleanArray>
   where
       T : TryInto<i128> + Copy + std::fmt::Debug
   {
       let right: i128 = right
           .try_into()
           .map_err(|_| ArrowError::ComputeError(format!("Can not convert 
scalar {:?} to i128", right)))?;
       match left.data_type() {
           DataType::UInt8 => {
               let right: u8 = right
                   .try_into()
                   .map_err(|_| ArrowError::ComputeError(format!("Can not 
convert {:?} to u8 for comparison with UInt8Array", right)))?;
               eq_scalar::<UInt8Type>(as_primitive::<UInt8Type>(left), right)
           }
           DataType::UInt16 => {
               let right: u16 = right
                   .try_into()
                   .map_err(|_| ArrowError::ComputeError(format!("Can not 
convert {:?} to u16 for comparison with UInt16Array", right)))?;
               eq_scalar::<UInt16Type>(as_primitive::<UInt16Type>(left), right)
           }
           // TODO macroize + fill out the other primitive array types here
   
           DataType::Dictionary(key_type, value_type) => {
               match key_type.as_ref() {
                   DataType::UInt8 => {
                       let left = as_dictionary::<UInt8Type>(left);
                       unpack_dict_comparison(left, 
eq_dyn_scalar(left.values().as_ref(), right)?)
                   }
                   // TODO fill out the rest of the key types here
                   _ => todo!()
               }
           }
           _ => todo!()
       }
   }
   
   /// unpacks the results of comparing left.values (as a boolean)
   ///
   /// TODO add example
   ///
   fn unpack_dict_comparison<K>(
       left: &DictionaryArray<K>,
       dict_comparison: BooleanArray,
   ) -> Result<BooleanArray>
   where
       K: ArrowNumericType,
   {
       assert_eq!(dict_comparison.len(), left.values().len());
   
       let result: BooleanArray = left
           .keys()
           .iter()
           .map(|key| {
               key.map(|key| unsafe {
                   // safety lengths were verified above
                   let key = key.to_usize().expect("Dictionary index not 
usize");
                   dict_comparison.value_unchecked(key)
               })
           })
           .collect();
   
       Ok(result)
   }
   
   ```
   
   
   Which then finally allows a call to `eq_dyn_scalar` without type annotations:
   
   ```rust
       #[test]
       fn test_dict_eq_scalar() {
           ...
           let array = builder.finish();
           // YAY! No type annotations!
           let a_eq = eq_dyn_scalar(&array, 123).unwrap();
           assert_eq!(
               a_eq,
               BooleanArray::from(vec![Some(true), None, Some(false)])
           );
       }
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to