/* * Copyright 2023 Stephen Tetley * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */////// Functions for converting between Flix and Java values and collections.///pubmod Adaptor {import java.lang.Objectimport java.util.ArrayListimport java.util.Collectionimport java.util.Comparatorimport java.util.{Iterator => JIterator}import java.util.LinkedListimport java.util.{List => JList}import java.util.{Map => JMap}import java.util.{Map$Entry => Entry}import java.util.Optionalimport java.util.{Set => JSet}import java.util.TreeMapimport java.util.TreeSetimport java.util.stream.BaseStreamimport java.util.stream.Stream////// Returns a comparator for elements of type `a`.////// The comparator is backed by the ordering on `a`.///pubdefcomparator(_: Proxy[a]): Comparator[a] \ IOwithOrder[a] =new Comparator[a] {def compare(_this: Comparator[a], t: a, u: a): Int32 =Order.compare(t, u) |> Comparison.toInt32 }////// Returns the given Java Optional as a Flix Option.///pubdeffromOptional(o: Optional[a]): Option[a] =if (o.isPresent()) {leto1 = o.get(); Some(o1) } else None////// Returns the given Java `Map.Entry` as a Flix tuple.///pubdeffromMapEntry(e: Entry[k, v]): (k, v) =letk1 = e.getKey();letv1 = e.getValue(); (k1, v1)////// Returns all elements in the given Java List as a Flix List.///pubdeffromList(l: JList[a]): List[a] = regionrc {defiterator(x) = unsafeIO { x.iterator() };iterator(l) |> fromIterator(rc, (Proxy.Proxy: Proxy[a])) |> Iterator.toList }////// Returns a Flix Iterator of the elements in the given Java List.///pubdeffromListToIterator(rc: Region[r], l: JList[a]): Iterator[a, r, r] \ r =defiterator(x) = unsafeIOasr { x.iterator() };iterator(l) |> fromIterator(rc, (Proxy.Proxy: Proxy[a]))////// Returns all elements in the given Java Set as a Flix Set.////// WARNING: The Flix Set will use the ordering defined on `a`.///pubdeffromSet(s: JSet[a]): Set[a] withOrder[a] = regionrc {defiterator(x) = unsafeIO { x.iterator() };iterator(s) |> fromIterator(rc, (Proxy.Proxy: Proxy[a])) |> Iterator.toSet }////// Returns a Flix Iterator of the elements in the given Java Set.///pubdeffromSetToIterator(rc: Region[r], s: JSet[a]): Iterator[a, r, r] \ r =defiterator(x) = unsafeIOasr { x.iterator() };iterator(s) |> fromIterator(rc, (Proxy.Proxy: Proxy[a]))////// Returns all key-value pairs in the given Java Map as a Flix Map.////// WARNING: The Flix Map will use the ordering defined on `k`.///pubdeffromMap(m: JMap[k, v]): Map[k, v] withOrder[k] = regionrc {defstep(acc, entry) = {let (k, v) = entry;Map.insert(k, v, acc) };fromMapToIterator(rc, m) |> Iterator.foldLeft(step, Map.empty()) }////// Returns a Flix Iterator of the key-value pairs in the given Java Map.///pubdeffromMapToIterator(rc: Region[r], m: JMap[k, v]): Iterator[(k, v), r, r] \ r =defentrySet(x) = unsafeIOasr { x.entrySet() };defiterator(x) = unsafeIOasr { x.iterator() };defhasNext(x) = unsafeIOasr { x.hasNext() };defnext(x) = unsafeIOasr { x.next() };letentries = entrySet(m);letiter = iterator(entries);letgetNext = () -> matchhasNext(iter) {casetrue => {letentry = next(iter);let (k, v) = fromMapEntry(entry); Some((k, v)) }casefalse => None };Iterator.unfoldWithIter(rc, getNext)////// Returns a fresh Flix `Iterator` from the Java iterator `iter`.///pubdeffromIterator(rc: Region[r], _: Proxy[a], iter: JIterator[a]): Iterator[a, r, r] =defhasNext(x) = unsafeIOasr { x.hasNext() };defnext(x) = unsafeIOasr { x.next() };letstep = () -> {matchhasNext(iter) {casetrue => next(iter) |> Somecasefalse => None } };letiterF = () -> (step());Iterator.unfoldWithIter(rc, iterF)////// Returns a Flix Iterator of the elements in the given Java Stream.///pubdeffromStreamToIterator(rc: Region[r], strm: Stream[a]): Iterator[a, r, r] \ r =letbaseStream: BaseStream[a, Stream[a]] = checked_cast(strm);letiter = unsafeIOasr { baseStream.iterator() };Adaptor.fromIterator(rc, (Proxy.Proxy: Proxy[a]), iter)////// Returns a Flix Iterator of the elements in the given Java Collection.///pubdeffromCollectionToIterator(rc: Region[r], col: Collection[a]): Iterator[a, r, r] \ r =letiter = unsafeIOasr { col.iterator() };Adaptor.fromIterator(rc, (Proxy.Proxy: Proxy[a]), iter)////// Returns the `o` as a new Java `Optional`.///pubdeftoOptional(o: Option[a]): Optional[a] \ IO =matcho {case None => Optional.empty()case Some(a) => Optional.of(a) }////// Returns the key-value pair `p` as a new Java `Map.Entry`.///pubdeftoMapEntry(p: (k, v)): Entry[k, v] \ IO =let (k, v) = p; JMap.entry(k, v)////// Alias for `toArrayList`.///pubdeftoList(ma: m[a]): JList[a] \ (IO + Foldable.Aef[m]) withFoldable[m] =checked_cast(toArrayList(ma))////// Returns the elements of the given foldable `ma` as a new Java `ArrayList`.////// Creates a fresh `ArrayList` and copies all elements in `ma` into it.///pubdeftoArrayList(ma: m[a]): ArrayList[a] \ (IO + Foldable.Aef[m]) withFoldable[m] =letalist: ArrayList[a] = new ArrayList();Foldable.forEach(x -> discardalist.add(x), ma);alist////// Returns the elements of the given foldable `ma` as a new Java `LinkedList`.////// Creates a fresh `LinkedList` and copies all elements in `ma` into it.///pubdeftoLinkedList(ma: m[a]): LinkedList[a] \ (IO + Foldable.Aef[m]) withFoldable[m] =letllist: LinkedList[a] = new LinkedList();Foldable.forEach(x -> discardllist.add(x), ma);llist////// Alias for `toTreeSet`.///pubdeftoSet(ma: m[a]): JSet[a] \ (IO + Foldable.Aef[m]) withOrder[a], Foldable[m] = checked_cast(toTreeSet(ma))////// Returns the elements of the given foldable `ma` as a new `TreeSet`.///pubdeftoTreeSet(ma: m[a]): TreeSet[a] \ (IO + Foldable.Aef[m]) withOrder[a], Foldable[m] =lettset: TreeSet[a] = new TreeSet();Foldable.forEach(x -> discardtset.add(x), ma);tset////// Alias for `toTreeMap`.///pubdeftoMap(m: Map[k, v]): JMap[k, v] \ IOwithOrder[k] = checked_cast(toTreeMap(m))////// Returns all key-value pairs of the given map `m` as a new `TreeMap`.////// The `TreeMap` uses a `Comparator` constructed from the `Order` on `k`.///pubdeftoTreeMap(m: Map[k, v]): TreeMap[k, v] \ IOwithOrder[k] =lettmap: TreeMap[k, v] = new TreeMap();Map.forEach((k, v) -> discardtmap.put(k, v), m);tmap}