message: Optimize blend.rs codes not to do unnecessary value.clone() for the last Rc value
diff: @@ -13,6 +13,20 @@ pub enum BlendError {
  FieldDefinitionNotSupported,
  }
  +enum Param<'a> {
  + Val(Value),
  + Ref(&'a Value),
  +}
  +
  +impl<'a> Into<Value> for Param<'a> {
  + fn into(self) -> Value {
  + match self {
  + Param::Val(value) => value,
  + Param::Ref(value) => value.clone(),
  + }
  + }
  +}
  +
  pub struct Blend<'a> {
  fields: &'a [FieldDefinitionExpression],
  }
  @@ -24,36 +38,53 @@ impl<'a> Blend<'a> {
  pub fn apply<T: 'static + Debug>(
  &self,
  - blend_context: Result<Rc<BlendContext<'a, T>>>,
  + context: Result<Rc<BlendContext<'a, T>>>,
  ) -> Result<Row> {
  - let &BlendContext {
  - columns, ref row, ..
  - } = &(*blend_context?);
  + self.blend(context?)
  + }
  - // TODO: Should support JOIN
  - self.blend(columns, row)
  + fn blend<T: 'static + Debug>(&self, context: Rc<BlendContext<'a, T>>) -> Result<Row> {
  + macro_rules! blend {
  + ($values: expr, $columns: expr) => {
  + $values
  + .zip($columns.iter())
  + .filter_map(|(value, column)| self.find(column, value))
  + .collect::<Result<_>>()
  + .map(Row)
  + };
  }
  - fn blend(&self, columns: &[Column], row: &Row) -> Result<Row> {
  + match Rc::try_unwrap(context) {
  + Ok(context) => {
  + let BlendContext { columns, row, .. } = context;
  +
  let Row(values) = row;
  - let values = values
  - .iter()
  - .zip(columns.iter())
  - .filter_map(|(value, column)| self.find(value, column))
  - .collect::<Result<_>>()?;
  + let values = values.into_iter().map(Param::Val);
  +
  + blend!(values, columns)
  + }
  + Err(context) => {
  + let &BlendContext {
  + columns, ref row, ..
  + } = &(*context);
  - Ok(Row(values))
  + let Row(values) = row;
  + let values = values.iter().map(|v| Param::Ref(&v));
  +
  + blend!(values, columns)
  + }
  + }
  }
  - fn find(&self, value: &Value, target: &Column) -> Option<Result<Value>> {
  + fn find(&self, target: &Column, value: Param) -> Option<Result<Value>> {
  for expr in self.fields {
  match expr {
  FieldDefinitionExpression::All => {
  - return Some(Ok(value.clone()));
  + return Some(Ok(value.into()));
  }
  FieldDefinitionExpression::Col(column) => {
  if column.name == target.name {
  - return Some(Ok(value.clone()));
  + return Some(Ok(value.into()));
  }
  }
  FieldDefinitionExpression::AllInTable(_) | FieldDefinitionExpression::Value(_) => {
  