-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

{- | This module contains implementation of 'UStore'.

@UStore@ is essentially 'Lorentz.Store.Store' modified for the sake of
upgradeability.

In API it differs from @Store@ in the following ways:
1. It keeps both virtual @big_map@s and plain fields;
2. Neat conversion between Michelson and Haskell values
is implemented;
3. Regarding composabililty, one can operate with one @UStore@
and then lift it to a bigger one which includes the former.
This allows for simpler management of stores and clearer error messages.
In spite of this, operations with 'UStore's over deeply nested templates will
still work as before.

We represent 'UStore' as @big_map bytes bytes@.

* Plain fields are stored as
@key = pack fieldName; value = pack originalValue@.

* Virtual @big_map@s are kept as
@key = pack (bigMapName, originalKey); value = pack originalValue@.

-}
module Lorentz.UStore
  ( -- * UStore and related type definitions
    UStore
  , type (|~>)(..)
  , UStoreFieldExt (..)
  , UStoreField
  , UStoreMarkerType
  , KnownUStoreMarker (..)

    -- ** Type-lookup-by-name
  , GetUStoreKey
  , GetUStoreValue
  , GetUStoreField
  , GetUStoreFieldMarker

    -- ** Instructions
  , ustoreMem
  , ustoreGet
  , ustoreUpdate
  , ustoreInsert
  , ustoreInsertNew
  , ustoreDelete

  , ustoreToField
  , ustoreGetField
  , ustoreSetField

    -- ** Instruction constraints
  , HasUStore
  , HasUField
  , HasUStoreForAllIn

    -- * UStore composability
  , liftUStore
  , unliftUStore

    -- * Documentation
  , UStoreTemplateHasDoc (..)
  , UStoreMarkerHasDoc (..)

    -- * UStore management from Haskell
  , mkUStore
  , ustoreDecompose
  , ustoreDecomposeFull
  , fillUStore
  , MkUStoreTW
  , DecomposeUStoreTW
  , FillUStoreTW

    -- * Migrations
  , MigrationScript (..)
  , MigrationScript_
  , UStoreMigration
  , migrationToScript
  , migrationToScriptI
  , migrationToLambda
  , mkUStoreMigration
  , mustoreToOld
  , migrateGetField
  , migrateAddField
  , migrateRemoveField
  , migrateExtractField
  , migrateOverwriteField
  , migrateModifyField

    -- * Extras
  , PickMarkedFields
  , UStoreTraversable
  ) where

import Lorentz.UStore.Types
import Lorentz.UStore.Instr
import Lorentz.UStore.Traversal
import Lorentz.UStore.Instances ()
import Lorentz.UStore.Haskell
import Lorentz.UStore.Doc
import Lorentz.UStore.Lift
import Lorentz.UStore.Migration