feat: impl<B> for (From/Into)Value for Cow<'_, B> where B::Owned: (From/Into)Value (#16380)

# Description
Implements `FromValue` and `IntoValue` for `Cow`, which makes it easy to
use it in types that need to implement these traits.

I don't think it will have a significant impact, but it can let us avoid
allocations where we can use static values.

# Tests + Formatting
No need, the implementations are delegated to `B::Owned`.

Co-authored-by: Bahex <Bahex@users.noreply.github.com>
This commit is contained in:
Bahex
2025-08-11 20:47:50 +03:00
committed by GitHub
parent 751ef6e8da
commit a4711af952
2 changed files with 39 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ use crate::{
use chrono::{DateTime, FixedOffset};
use std::{
any,
borrow::Cow,
cmp::Ordering,
collections::{HashMap, VecDeque},
fmt,
@@ -564,6 +565,25 @@ where
}
}
/// This blanket implementation permits the use of [`Cow<'_, B>`] ([`Cow<'_, str>`] etc) based on
/// the [FromValue] implementation of `B`'s owned form ([str] => [String]).
///
/// It's meant to make using the [FromValue] derive macro on types that contain [Cow] fields
/// possible.
impl<B> FromValue for Cow<'_, B>
where
B: ?Sized + ToOwned,
B::Owned: FromValue,
{
fn from_value(v: Value) -> Result<Self, ShellError> {
<B::Owned as FromValue>::from_value(v).map(Cow::Owned)
}
fn expected_type() -> Type {
<B::Owned as FromValue>::expected_type()
}
}
impl<V> FromValue for HashMap<String, V>
where
V: FromValue,

View File

@@ -1,6 +1,9 @@
use crate::{Range, Record, ShellError, Span, Value, ast::CellPath, engine::Closure};
use chrono::{DateTime, FixedOffset};
use std::{borrow::Borrow, collections::HashMap};
use std::{
borrow::{Borrow, Cow},
collections::HashMap,
};
/// A trait for converting a value into a [`Value`].
///
@@ -202,6 +205,21 @@ where
}
}
/// This blanket implementation permits the use of [`Cow<'_, B>`] ([`Cow<'_, str>`] etc) based on
/// the [IntoValue] implementation of `B`'s owned form ([str] => [String]).
///
/// It's meant to make using the [IntoValue] derive macro on types that contain [Cow] fields
/// possible.
impl<B> IntoValue for Cow<'_, B>
where
B: ?Sized + ToOwned,
B::Owned: IntoValue,
{
fn into_value(self, span: Span) -> Value {
<B::Owned as IntoValue>::into_value(self.into_owned(), span)
}
}
impl<K, V> IntoValue for HashMap<K, V>
where
K: Borrow<str> + Into<String>,