1 /*
2  * Copyright (C) 2024 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.intentresolver.util.cursor
18 
19 import android.database.Cursor
20 
21 /** A [Cursor] that holds values of [E] for each row. */
22 interface CursorView<out E> : Cursor {
23     /**
24      * Reads the current row from this [CursorView]. A result of `null` indicates that the row could
25      * not be read / value could not be produced.
26      */
readRownull27     fun readRow(): E?
28 }
29 
30 /**
31  * Returns a [CursorView] from the given [Cursor], and a function [readRow] used to produce the
32  * value for a single row.
33  */
34 fun <E> Cursor.viewBy(readRow: Cursor.() -> E): CursorView<E> =
35     object : CursorView<E>, Cursor by this@viewBy {
36         override fun readRow(): E? = immobilized().readRow()
37     }
38 
39 /** Returns a [CursorView] that begins (index 0) at [newStartIndex] of the given cursor. */
startAtnull40 fun <E> CursorView<E>.startAt(newStartIndex: Int): CursorView<E> =
41     object : CursorView<E>, Cursor by (this@startAt as Cursor).startAt(newStartIndex) {
42         override fun readRow(): E? = this@startAt.readRow()
43     }
44 
45 /** Returns a [CursorView] that is truncated to contain only [count] elements. */
limitnull46 fun <E> CursorView<E>.limit(count: Int): CursorView<E> =
47     object : CursorView<E>, Cursor by (this@limit as Cursor).limit(count) {
48         override fun readRow(): E? = this@limit.readRow()
49     }
50 
51 /** Retrieves a single row at index [idx] from the [CursorView]. */
getnull52 operator fun <E> CursorView<E>.get(idx: Int): E? = if (moveToPosition(idx)) readRow() else null
53 
54 /** Returns a [Sequence] that iterates over the [CursorView] returning each row. */
55 fun <E> CursorView<E>.asSequence(): Sequence<E?> = sequence {
56     for (i in 0 until count) {
57         yield(get(i))
58     }
59 }
60