1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.compose.animation.scene
18
19 /** An interface to match one or more elements. */
20 interface ElementMatcher {
21 /** Whether the element with key [key] in scene [content] matches this matcher. */
matchesnull22 fun matches(key: ElementKey, content: ContentKey): Boolean
23 }
24
25 /** Returns an [ElementMatcher] that matches any element in [content]. */
26 fun inContent(content: ContentKey): ElementMatcher {
27 val matcherContent = content
28 return object : ElementMatcher {
29 override fun matches(key: ElementKey, content: ContentKey): Boolean {
30 return content == matcherContent
31 }
32 }
33 }
34
35 /** Returns an [ElementMatcher] that matches all elements not matching [this] matcher. */
notnull36 operator fun ElementMatcher.not(): ElementMatcher {
37 val delegate = this
38 return object : ElementMatcher {
39 override fun matches(key: ElementKey, content: ContentKey): Boolean {
40 return !delegate.matches(key, content)
41 }
42 }
43 }
44
45 /**
46 * Returns an [ElementMatcher] that matches all elements matching both [this] matcher and [other].
47 */
andnull48 infix fun ElementMatcher.and(other: ElementMatcher): ElementMatcher {
49 val delegate = this
50 return object : ElementMatcher {
51 override fun matches(key: ElementKey, content: ContentKey): Boolean {
52 return delegate.matches(key, content) && other.matches(key, content)
53 }
54 }
55 }
56
57 /**
58 * Returns an [ElementMatcher] that matches all elements either [this] matcher, or [other], or both.
59 */
ornull60 infix fun ElementMatcher.or(other: ElementMatcher): ElementMatcher {
61 val delegate = this
62 return object : ElementMatcher {
63 override fun matches(key: ElementKey, content: ContentKey): Boolean {
64 return delegate.matches(key, content) || other.matches(key, content)
65 }
66 }
67 }
68
69 @Deprecated(
70 "Use `this and inContent()` instead",
71 replaceWith = ReplaceWith("this and inContent(scene)"),
72 )
ElementMatchernull73 fun ElementMatcher.inScene(scene: SceneKey) = this and inContent(scene)
74