summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Perehonchuk <romanp@meta.com>2024-10-01 02:42:33 -0700
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>2024-10-01 02:42:33 -0700
commit35ea4c97b0ea05f41835b1c0ddb28ba6e96a9429 (patch)
tree5b46e697e775134f16158b3ecd64a476f3503ed1
parent34930ceea65028fe0947d35228b6119634c0cd24 (diff)
bit and
Summary: this diff was split from the next one Reviewed By: stepancheg Differential Revision: D63526160 fbshipit-source-id: e08cc0be755597afdd301181953a2e81e665db05
-rw-r--r--starlark/src/values/types/set/value.rs46
-rw-r--r--starlark/testcases/eval/go/set.star6
2 files changed, 49 insertions, 3 deletions
diff --git a/starlark/src/values/types/set/value.rs b/starlark/src/values/types/set/value.rs
index 3158e7f8..2212a406 100644
--- a/starlark/src/values/types/set/value.rs
+++ b/starlark/src/values/types/set/value.rs
@@ -258,6 +258,24 @@ where
}
Ok(heap.alloc(SetData { content: items }))
}
+
+ // Set intersection
+ fn bit_and(&self, rhs: Value<'v>, heap: &'v Heap) -> crate::Result<Value<'v>> {
+ let mut items = SmallSet::new();
+ if self.0.content().is_empty() {
+ return Ok(heap.alloc(SetData { content: items }));
+ }
+ let rhs = SetRef::from_value(rhs)
+ .map_or_else(|| ValueError::unsupported_with(self, "&", rhs), Ok)?;
+
+ for h in rhs.iter_hashed() {
+ if self.0.content().contains_hashed(h.as_ref()) {
+ items.insert_hashed_unique_unchecked(h);
+ }
+ }
+
+ Ok(heap.alloc(SetData { content: items }))
+ }
}
impl<'v, T: SetLike<'v>> Serialize for SetGen<T> {
@@ -306,4 +324,32 @@ mod tests {
fn test_bit_or_ord() {
assert::eq("list(set([5, 1, 3]) | set([4, 5, 2]))", "[5, 1, 3, 4, 2]")
}
+
+ #[test]
+ fn test_bit_and() {
+ assert::eq("set([1, 2, 3]) & set([3, 4])", "set([3])")
+ }
+
+ #[test]
+ fn test_bit_and_lhs_empty() {
+ assert::eq("set() & set([3, 4])", "set([])")
+ }
+
+ #[test]
+ fn test_bit_and_rhs_empty() {
+ assert::eq("set([1, 2, 3]) & set()", "set([])")
+ }
+
+ #[test]
+ fn test_bit_and_ord() {
+ assert::eq("list(set([1, 2, 3]) & set([4, 3, 1]))", "[3, 1]")
+ }
+
+ #[test]
+ fn test_bit_and_fail_iter() {
+ assert::fail(
+ "set([1, 2, 3]) & []",
+ "Operation `&` not supported for types `set` and `list`",
+ );
+ }
}
diff --git a/starlark/testcases/eval/go/set.star b/starlark/testcases/eval/go/set.star
index 77ca85a0..0945b643 100644
--- a/starlark/testcases/eval/go/set.star
+++ b/starlark/testcases/eval/go/set.star
@@ -67,9 +67,9 @@ asserts.eq(list(x.union([5, 1])), [1, 2, 3, 5])
asserts.eq(list(x.union((6, 5, 4))), [1, 2, 3, 6, 5, 4])
asserts.fails(lambda : x.union([1, 2, {}]), "unhashable type: dict")
-# # intersection, set & set or set.intersection(iterable)
-# asserts.eq(list(set("a".elems()) & set("b".elems())), [])
-# asserts.eq(list(set("ab".elems()) & set("bc".elems())), ["b"])
+# intersection, set & set or set.intersection(iterable)
+asserts.eq(list(set("a".elems()) & set("b".elems())), [])
+asserts.eq(list(set("ab".elems()) & set("bc".elems())), ["b"])
# asserts.eq(list(set("a".elems()).intersection("b".elems())), [])
# asserts.eq(list(set("ab".elems()).intersection("bc".elems())), ["b"])