summaryrefslogtreecommitdiff
path: root/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala
blob: f215e6e054bd93310a28f841191e9d5232caa4eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*                     __                                               *\
**     ________ ___   / /  ___      __ ____  Scala.js API               **
**    / __/ __// _ | / /  / _ | __ / // __/  (c) 2013, LAMP/EPFL        **
**  __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \    http://scala-lang.org/     **
** /____/\___/_/ |_/____/_/ | |__/ /____/                               **
**                          |/____/                                     **
\*                                                                      */

package scala.scalajs.js

import scala.collection.mutable
import mutable.Builder

import scala.collection.generic.CanBuildFrom

/** Wrapper to use a js.Dictionary as a scala.mutable.Map */
@inline
class WrappedDictionary[A](val dict: Dictionary[A])
    extends mutable.AbstractMap[String, A]
       with mutable.Map[String, A]
       with mutable.MapLike[String, A, WrappedDictionary[A]] {

  def get(key: String): Option[A] = {
    if (contains(key))
      Some(dict(key))
    else
      None
  }

  override def contains(key: String): Boolean =
    dict.hasOwnProperty(key)

  def -=(key: String): this.type = {
    dict.delete(key)
    this
  }

  def +=(kv: (String, A)): this.type = {
    dict(kv._1) = kv._2
    this
  }

  def iterator: Iterator[(String, A)] = new Iterator[(String, A)] {
    private[this] val keys = Object.keys(dict)
    private[this] var index: Int = 0
    def hasNext(): Boolean = index < keys.length
    def next(): (String, A) = {
      val key = keys(index)
      index += 1
      (key, dict(key))
    }
  }

  override def keys: Iterable[String] =
    Object.keys(dict)

  override def empty: WrappedDictionary[A] =
    new WrappedDictionary(Dictionary.empty)

}

object WrappedDictionary {
  // Note: We can't extend MutableMapFactory[WrappedDictionary] since
  // it requires support for any type of key

  def empty[A]: WrappedDictionary[A] = new WrappedDictionary(Dictionary.empty)

  type CBF[A] = CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]]
  implicit def canBuildFrom[A]: CBF[A] = new CBF[A] {
    def apply(from: WrappedDictionary[_]): Builder[(String, A), WrappedDictionary[A]] =
      new WrappedDictionaryBuilder[A]
    def apply(): Builder[(String, A), WrappedDictionary[A]] =
      new WrappedDictionaryBuilder[A]
  }

  class WrappedDictionaryBuilder[A]
      extends Builder[(String, A), WrappedDictionary[A]] {
    private[this] var dict: Dictionary[A] = Dictionary.empty
    def +=(elem: (String, A)): this.type = {
      dict(elem._1) = elem._2
      this
    }
    def clear(): Unit =
      dict = Dictionary.empty
    def result(): WrappedDictionary[A] =
      new WrappedDictionary(dict)
  }

}