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

s_mach.datadiff.package.scala Maven / Gradle / Ivy

/*
                    ,i::,
               :;;;;;;;
              ;:,,::;.
            1ft1;::;1tL
              t1;::;1,
               :;::;               _____       __  ___              __
          fCLff ;:: tfLLC         / ___/      /  |/  /____ _ _____ / /_
         CLft11 :,, i1tffLi       \__ \ ____ / /|_/ // __ `// ___// __ \
         1t1i   .;;   .1tf       ___/ //___// /  / // /_/ // /__ / / / /
       CLt1i    :,:    .1tfL.   /____/     /_/  /_/ \__,_/ \___//_/ /_/
       Lft1,:;:       , 1tfL:
       ;it1i ,,,:::;;;::1tti      s_mach.datadiff
         .t1i .,::;;; ;1tt        Copyright (c) 2014 S-Mach, Inc.
         Lft11ii;::;ii1tfL:       Author: [email protected]
          .L1 1tt1ttt,,Li
            ...1LLLL...
*/
package s_mach

package object datadiff extends
  TupleDataDiffImplicits with
  CollectionDataDiffImplicits with
  DataTypeDataDiffImplicits {

  trait InferDataDiff[A] {
    def infer[P](implicit ev:DataDiff[A,P]) : DataDiff[A,P]
  }

  /**
   * Get the DataDiff instance for a type by inferring the patch type
   * @tparam A the type
   * @return a temporary instance that can infer the DataDiff instance
   */
  def dataDiff[A] = new InferDataDiff[A] {
    /** @return the DataDiff implementation for A */
    def infer[P](implicit aDiff:DataDiff[A,P]) = aDiff
  }

  trait InferPatch[A] extends InferDataDiff[A] {
    def noChange[P](implicit ev:DataDiff[A,P]) : P
  }
  def patchFor[A] = new InferPatch[A] {
    /** @return the DataDiff implementation for A */
    def infer[P](implicit aDiff:DataDiff[A,P]) = aDiff
    /** @return the noChange value for the patch type for A */
    def noChange[P](implicit aDiff:DataDiff[A,P]) : P = aDiff.noChange
  }

  implicit class SMach_Datadiff_PimpEverything[A](val self: A) extends AnyVal {

    /**
     * Compute the difference between two values. Result is a patch that if
     * applied to the original value results in the new value.
     * @param newValue the new value
     * @return If oldValue and newValue are different, P (that is not equal to
     *         noChange). Otherwise, noChange
     */
    def calcDiff[Patch](
      newValue: A
    )(implicit
      aDiff:DataDiff[A,Patch]
    ) : Patch =
      aDiff.calcDiff(self, newValue)

    /** Alias for calcDiff. See above */
    def -->?[Patch](
      other: A
    )(implicit
      aDiff:DataDiff[A,Patch]
    ) : Patch =
      aDiff.calcDiff(self, other)

    /**
     * Apply a patch (generated by a prior call to calcDiff) to a value. If patch
     * is equal to noChange, then value is returned unmodified.
     * @param patch the patch to apply
     * @return the new value with the patch applied
     */
    def applyPatch[Patch](
      patch: Patch
    )(implicit
      aDiff:DataDiff[A,Patch]
    ) : A = aDiff.applyPatch(self, patch)

    /** Alias for applyPatch. See above */
    def |<--[Patch](
      patch: Patch
    )(implicit
      aDiff:DataDiff[A,Patch]
    ) : A = applyPatch(patch)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy