Skip to content

Commit

Permalink
changed warning message, optimised is_path_(a_string/an_option) fun…
Browse files Browse the repository at this point in the history
…ctions
  • Loading branch information
its-the-shrimp committed Aug 21, 2023
1 parent 97cecf3 commit d7c868a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 47 deletions.
76 changes: 31 additions & 45 deletions packages/yew-macro/src/derive_props/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,22 +297,16 @@ impl<'a> PropFieldCheck<'a> {
}
}

fn is_path_segments_an_option(path_segments: impl Iterator<Item = String>) -> bool {
fn is_option_path_seg(seg_index: usize, path: &str) -> u8 {
match (seg_index, path) {
(0, "core") => 0b001,
(0, "std") => 0b001,
(0, "Option") => 0b111,
(1, "option") => 0b010,
(2, "Option") => 0b100,
_ => 0,
}
}

path_segments
.enumerate()
.fold(0, |flags, (i, ps)| flags | is_option_path_seg(i, &ps))
== 0b111
fn is_path_segments_an_option<T>(mut iter: impl Iterator<Item = T>) -> bool
where
for<'a> T: PartialEq<&'a str>,
{
iter.next().is_some_and(|first| {
first == "Option"
|| (first == "std" || first == "core")
&& iter.next().is_some_and(|x| x == "option")
&& iter.next().is_some_and(|x| x == "Option")
})
}

/// Returns true when the [`Path`] seems like an [`Option`] type.
Expand All @@ -324,25 +318,19 @@ fn is_path_segments_an_option(path_segments: impl Iterator<Item = String>) -> bo
///
/// Users can define their own [`Option`] type and this will return true - this is unavoidable.
fn is_path_an_option(path: &Path) -> bool {
is_path_segments_an_option(path.segments.iter().take(3).map(|ps| ps.ident.to_string()))
is_path_segments_an_option(path.segments.iter().map(|ps| &ps.ident))
}

fn is_path_segments_a_string(path_segments: impl Iterator<Item = String>) -> bool {
fn is_string_path_seg(seg_index: usize, path: &str) -> u8 {
match (seg_index, path) {
(0, "alloc") => 0b001,
(0, "std") => 0b001,
(0, "String") => 0b111,
(1, "string") => 0b010,
(2, "String") => 0b100,
_ => 0,
}
}

path_segments
.enumerate()
.fold(0, |flags, (i, ps)| flags | is_string_path_seg(i, &ps))
== 0b111
fn is_path_segments_a_string<T>(mut iter: impl Iterator<Item = T>) -> bool
where
for<'a> T: PartialEq<&'a str>,
{
iter.next().is_some_and(|first| {
first == "String"
|| (first == "std" || first == "alloc")
&& iter.next().is_some_and(|x| x == "string")
&& iter.next().is_some_and(|x| x == "String")
})
}

/// returns true when the [`Path`] seems like a [`String`] type.
Expand All @@ -352,7 +340,7 @@ fn is_path_segments_a_string(path_segments: impl Iterator<Item = String>) -> boo
/// - alloc::string::String
/// - String
pub(crate) fn is_path_a_string(path: &Path) -> bool {
is_path_segments_a_string(path.segments.iter().map(|ps| ps.ident.to_string()))
is_path_segments_a_string(path.segments.iter().map(|ps| &ps.ident))
}

impl TryFrom<Field> for PropField {
Expand Down Expand Up @@ -411,35 +399,33 @@ impl PartialEq for PropField {

#[cfg(test)]
mod tests {
use std::iter::once;

use crate::derive_props::field::{is_path_segments_a_string, is_path_segments_an_option};

#[test]
fn all_std_and_core_option_path_seg_return_true() {
assert!(is_path_segments_an_option(
vec!["core".to_owned(), "option".to_owned(), "Option".to_owned()].into_iter()
));
assert!(is_path_segments_an_option(
vec!["std".to_owned(), "option".to_owned(), "Option".to_owned()].into_iter()
["core", "option", "Option"].into_iter()
));
assert!(is_path_segments_an_option(
vec!["Option".to_owned()].into_iter()
["std", "option", "Option"].into_iter()
));
assert!(is_path_segments_an_option(once("Option")));
// why OR instead of XOR
assert!(is_path_segments_an_option(
vec!["Option".to_owned(), "Vec".to_owned(), "Option".to_owned()].into_iter()
["Option", "Vec", "Option"].into_iter()
));
}

#[test]
fn all_std_and_alloc_string_seg_return_true() {
assert!(is_path_segments_a_string(
vec!["alloc".to_owned(), "string".to_owned(), "String".to_owned()].into_iter()
));
assert!(is_path_segments_a_string(
vec!["std".to_owned(), "string".to_owned(), "String".to_owned()].into_iter()
["alloc", "string", "String"].into_iter()
));
assert!(is_path_segments_a_string(
vec!["String".to_owned()].into_iter()
["std", "string", "String"].into_iter()
));
assert!(is_path_segments_a_string(once("String")));
}
}
4 changes: 2 additions & 2 deletions packages/yew-macro/src/derive_props/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ impl ToTokens for DerivePropsInput {
Type::Path(TypePath { qself: None, path }) if is_path_a_string(path) => {
emit_warning!(
path.span(),
"storing string values with `String` is deprecated, use `AttrValue` \
instead."
"storing string values with `String` is not recommended, prefer `AttrValue`.\n\
for further info visit https://yew.rs/docs/concepts/function-components/properties#anti-patterns"
)
}
_ => (),
Expand Down

0 comments on commit d7c868a

Please sign in to comment.