All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.raquo.laminar.inserters.CollectionCommand.scala Maven / Gradle / Ivy

The newest version!
package com.raquo.laminar.inserters

import com.raquo.laminar.nodes.ChildNode

sealed trait CollectionCommand[+Item] {

  @inline def map[A](project: Item => A): CollectionCommand[A]
}

object CollectionCommand {

  type Base = CollectionCommand[ChildNode.Base]

  case class Append[+Item](item: Item) extends CollectionCommand[Item] {

    @inline override def map[A](project: Item => A): Append[A] = {
      Append(project(item))
    }
  }

  case class Prepend[+Item](item: Item) extends CollectionCommand[Item] {

    @inline override def map[A](project: Item => A): Prepend[A] = {
      Prepend(project(item))
    }
  }

  case class Insert[+Item](item: Item, atIndex: Int) extends CollectionCommand[Item] {

    @inline override def map[A](project: Item => A): Insert[A] = {
      Insert(project(item), atIndex)
    }
  }

  case class Remove[+Item](item: Item) extends CollectionCommand[Item] {

    @inline override def map[A](project: Item => A): Remove[A] = {
      Remove(project(item))
    }
  }

  case class Replace[+Item](oldItem: Item, newItem: Item) extends CollectionCommand[Item] {

    @inline override def map[A](project: Item => A): Replace[A] = {
      Replace(project(oldItem), project(newItem))
    }
  }

  // @TODO[Performance,Integrity] Is Vector an appropriate data structure for our use case? Maybe use SortedSet, or TreeSet?
  // @TODO[Performance] Actually, seeing as this interface is intended for performance, js.Array is probably a better choice

  // @TODO[Test] vectorProcessor needs unit testing
  // @TODO Why do we even keep this `vectorProcessor` thing around? We don't use it.

  def vectorProcessor[Item](prevItems: Vector[Item], command: CollectionCommand[Item]): Vector[Item] = {
    command match {
      case Append(item) =>
        prevItems :+ item

      case Prepend(item) =>
        item +: prevItems

      case Insert(item, atIndex) =>
        // @TODO[Integrity] handle out of bound index
        val chunks = prevItems.splitAt(atIndex)
        (chunks._1 :+ item) ++ chunks._2

      case Remove(item) =>
        val index = prevItems.indexOf(item)
        if (index == -1) {
          prevItems
        } else if (index == 0) {
          prevItems.drop(1)
        } else {
          prevItems.take(index) ++ prevItems.drop(index + 1)
        }

      case Replace(oldItem, newItem) =>
        val index = prevItems.indexOf(oldItem)
        if (index == -1) {
          prevItems
        } else {
          prevItems.updated(index, newItem)
        }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy