text: # Copyright 2021 eprbell
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  from enum import Enum
  from typing import Optional, Set
  
  from rp2.configuration import Configuration
  from rp2.rp2_error import RP2TypeError, RP2ValueError
  
  
  class TransactionType(Enum):
      AIRDROP: str = "airdrop"
      BUY: str = "buy"
      DONATE: str = "donate"
      GIFT: str = "gift"
      HARDFORK: str = "hardfork"
      INTEREST: str = "interest"
      MINING: str = "mining"
      MOVE: str = "move"
      SELL: str = "sell"
      STAKING: str = "staking"
      WAGES: str = "wages"
  
      @classmethod
      def has_value(cls, value: str) -> bool:
          return value in _transaction_type_values
  
      @classmethod
      def type_check_from_string(cls, name: str, transaction_type: str) -> "TransactionType":
          Configuration.type_check_string(name, transaction_type)
          if not TransactionType.has_value(transaction_type.lower()):
              raise RP2ValueError(f"Parameter '{name}' has invalid transaction type value: {transaction_type}")
          return TransactionType[transaction_type.upper()]
  
      @classmethod
      def type_check(cls, name: str, transaction_type: "TransactionType") -> "TransactionType":
          Configuration.type_check_parameter_name(name)
          if not isinstance(transaction_type, cls):
              raise RP2TypeError(f"Parameter '{name}' is not of type {cls.__name__}: {transaction_type}")
          return transaction_type
  
      def is_earn_type(self) -> bool:
          return self in _transaction_type_earn_values
  
  
  _transaction_type_values: Set[str] = {item.value for item in TransactionType}
  _transaction_type_earn_values: Set[TransactionType] = {
      TransactionType.AIRDROP,
      TransactionType.HARDFORK,
      TransactionType.INTEREST,
      TransactionType.MINING,
      TransactionType.STAKING,
      TransactionType.WAGES,
  }
  
  
  class EntrySetType(Enum):
      IN: str = "in"
      INTRA: str = "intra"
      MIXED: str = "mixed"
      OUT: str = "out"
  
      @classmethod
      def has_value(cls, value: str) -> bool:
          return value in _entry_set_type_values
  
      @classmethod
      def get_entry_set_type_from_string(cls, entry_set_type: str) -> Optional["EntrySetType"]:
          if not isinstance(entry_set_type, str):
              # Disable mypy because otherwise it warns about unreachable code (we still want this runtime check)
              return None  # type: ignore
          if not EntrySetType.has_value(entry_set_type.lower()):
              return None
          return EntrySetType[entry_set_type.upper()]
  
      @classmethod
      def type_check_from_string(cls, name: str, entry_set_type: str) -> "EntrySetType":
          Configuration.type_check_string(name, entry_set_type)
          if not isinstance(entry_set_type, str):
              raise RP2TypeError(f"Parameter '{name}' is not of type string: {entry_set_type}")
          result = cls.get_entry_set_type_from_string(entry_set_type)
          if result is None:
              raise RP2ValueError(f"Parameter '{name}' has invalid entry set type value: {entry_set_type}")
          return result
  
      @classmethod
      def type_check(cls, name: str, entry_set_type: "EntrySetType") -> "EntrySetType":
          Configuration.type_check_parameter_name(name)
          if not isinstance(entry_set_type, cls):
              raise RP2TypeError(f"Parameter '{name}' is not of type {cls.__name__}: {entry_set_type}")
          return entry_set_type
  
  
  _entry_set_type_values: Set[str] = {item.value for item in EntrySetType}
  