BCUtils.BitFlags (bc_utils v0.11.0)

This module is used to manipulate bitwise flags.

Inspired by: Flags in C#

Event sourced systems often rely on flags to indicate the state of the aggregate at any given time. In essence, an event sourced aggregate is a finite state machine and this state is often represented as a set of flags, to be used as a shorthand for the state of the aggregate.

In this module, we define a set of functions that can be used to manipulate these flags.

Summary

Functions

Returs true if the given flag is set in the target state. In other words, it returns true if the bit that corresponds to the flag is set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flag to be checked is 0b01000000 (integer: 64) THEN the result is true

Returns true if ALL the flags are set in the target state. In other words, it returns true if ALL the bits that correspond to the flags are set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flags to be checked are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is true AND WHEN the flags to be checked are [0b01000000, 0b00000100] (integers: 64, 8) THEN the result is false

Returns true if any of the flags are set in the target state. In other words, it returns true if any of the bits that correspond to the flags are set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flags to be checked are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is true

Returns true if the given flag is NOT set in the target state. In other words, it returns true if the bit that corresponds to the flag is NOT set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flag to be checked is 0b01000000 (integer: 64) THEN the result is false AND WHEN the flag to be checked is 0b00000100 (integer: 8) THEN the result is true

Returns the highest flag in the target state. GIVEN: target_state is 0b01100100 (integer: 100)
AND the flag_map is

Returns the lowest flag in the bit flag map. GIVEN: target_state is 0b01100100 (integer: 100) AND the flag_map is

Returns the bitwise OR of multiple flags against a given state. In other words, it sets the bits that corresopnds to the flags GIVEN: original_state is 0b00100100 (integer: 36) WHEN the flags to be set are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is 0b11100100 (integer: 228)

Returns a list of flag descriptions that are set in the target state. GIVEN: original_state is 0b01100100 (integer: 100) AND the flag_map is

Returns a string representation of the bit flags. GIVEN: target_state is 0b01100100 (integer: 100) AND the flag_map is

Returns the bitwise AND of multiple flags against a given state. In other words, it unsets the bits that corresopnds to the flags GIVEN: original_state is 0b11100100 (integer: 228) WHEN the flags to be unset are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is 0b00100100 (integer: 36)

Functions

decompose(target)

has?(target, flag)

Returs true if the given flag is set in the target state. In other words, it returns true if the bit that corresponds to the flag is set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flag to be checked is 0b01000000 (integer: 64) THEN the result is true

Example: iex> BitFlags.has?(100, 64) true

has_all?(status, flags)

Returns true if ALL the flags are set in the target state. In other words, it returns true if ALL the bits that correspond to the flags are set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flags to be checked are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is true AND WHEN the flags to be checked are [0b01000000, 0b00000100] (integers: 64, 8) THEN the result is false

Example: iex> BitFlags.has_all?(100, [64, 128]) true iex> BitFlags.has_all?(100, [64, 8]) false

has_any?(status, flags)

Returns true if any of the flags are set in the target state. In other words, it returns true if any of the bits that correspond to the flags are set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flags to be checked are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is true

Example: iex> BitFlags.has_any?(100, [64, 128]) true

has_not?(target, flag)

Returns true if the given flag is NOT set in the target state. In other words, it returns true if the bit that corresponds to the flag is NOT set. GIVEN: original_state is 0b01100100 (integer: 100) WHEN the flag to be checked is 0b01000000 (integer: 64) THEN the result is false AND WHEN the flag to be checked is 0b00000100 (integer: 8) THEN the result is true

Example: iex> BitFlags.has_not?(100, 64) false iex> BitFlags.has_not?(100, 8) true

highest(n, flag_map)

Returns the highest flag in the target state. GIVEN: target_state is 0b01100100 (integer: 100)
AND the flag_map is:

  %{
     0 => "None",
     1 => "Ready",
     2 => "In Progress",
     4 => "Completed",
     8 => "Cancelled",
     16 => "Failed",
     32 => "Archived",
     64 => "Ready to Archive",
     128 => "Ready to Publish",
  }

THEN the result is Ready to Archive

Example: iex> descriptions = ...> %{ ...> 0 => "None", ...> 1 => "Ready", ...> 2 => "In Progress", ...> 4 => "Completed", ...> 8 => "Cancelled", ...> 16 => "Failed", ...> 32 => "Archived", ...> 64 => "Ready to Archive", ...> 128 => "Ready to Publish", ...> } %{

 0 => "None",
 1 => "Ready",
 2 => "In Progress",
 4 => "Completed",
 8 => "Cancelled",
 16 => "Failed",
 32 => "Archived",
 64 => "Ready to Archive",
 128 => "Ready to Publish",

} iex> BitFlags.highest(100, descriptions) "Ready to Archive"

lowest(n, flag_map)

Returns the lowest flag in the bit flag map. GIVEN: target_state is 0b01100100 (integer: 100) AND the flag_map is:

  %{
     0 => "None",
     1 => "Ready",
     2 => "In Progress",
     4 => "Completed",
     8 => "Cancelled",
     16 => "Failed",
     32 => "Archived",
     64 => "Ready to Archive",
     128 => "Ready to Publish",
  }

THEN the result is Ready

Example: iex> descriptions = ...> %{ ...> 0 => "None", ...> 1 => "Ready", ...> 2 => "In Progress", ...> 4 => "Completed", ...> 8 => "Cancelled", ...> 16 => "Failed", ...> 32 => "Archived", ...> 64 => "Ready to Archive", ...> 128 => "Ready to Publish", ...> } %{

 0 => "None",
 1 => "Ready",
 2 => "In Progress",
 4 => "Completed",
 8 => "Cancelled",
 16 => "Failed",
 32 => "Archived",
 64 => "Ready to Archive",
 128 => "Ready to Publish",

} iex> BitFlags.lowest(100, descriptions) "Ready"

set(target, flag)

Description

Returns the bitwise OR of two flags. In other words, it sets the bit that corresopnds to the flag

  • GIVEN: original_state is 0b00100100 (integer: 36)
  • WHEN the flag to be set is 0b01000000 (integer: 64)
  • THEN the result is 0b01100100 (integer: 100)

Parameters

  • target: the integer to be set
  • flag: the integer to be set

Output

The integer representation of the state after setting the flag

Examples

iex> BitFlags.set(36, 64) 100

set_all(target, flags)

Returns the bitwise OR of multiple flags against a given state. In other words, it sets the bits that corresopnds to the flags GIVEN: original_state is 0b00100100 (integer: 36) WHEN the flags to be set are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is 0b11100100 (integer: 228)

Example: iex> BitFlags.set_all(36, [64, 128]) 228

to_list(n, flag_map)

Returns a list of flag descriptions that are set in the target state. GIVEN: original_state is 0b01100100 (integer: 100) AND the flag_map is:

 %{
    0 => "None",
    1 => "Ready",
    2 => "In Progress",
    4 => "Completed",
    8 => "Cancelled",
    16 => "Failed",
    32 => "Archived",
    64 => "Ready to Archive",
    128 => "Ready to Publish",
    256 => "Published",
    512 => "Unpublished",
 }

WHEN the target state is 0b01100100 (integer: 100) THEN the result is ["Completed", "Archived", "Ready to Archive"]

Example: iex> descriptions = ...> %{ ...> 0 => "None", ...> 1 => "Ready", ...> 2 => "In Progress", ...> 4 => "Completed", ...> 8 => "Cancelled", ...> 16 => "Failed", ...> 32 => "Archived", ...> 64 => "Ready to Archive", ...> 128 => "Ready to Publish", ...> 256 => "Published", ...> 512 => "Unpublished", ...> } iex> BitFlags.to_list(100, descriptions) ["Completed", "Archived", "Ready to Archive"]

to_string(n, flag_map)

Returns a string representation of the bit flags. GIVEN: target_state is 0b01100100 (integer: 100) AND the flag_map is:

   %{
     0 => "None",
     1 => "Ready",
     2 => "In Progress",
     4 => "Completed",
     8 => "Cancelled",
     16 => "Failed",
     32 => "Archived",
     64 => "Ready to Archive",
     128 => "Ready to Publish",
  }

THEN the result is "Completed, Archived, Ready to Archive"

Example: iex> descriptions = ...> %{ ...> 0 => "None", ...> 1 => "Ready", ...> 2 => "In Progress", ...> 4 => "Completed", ...> 8 => "Cancelled", ...> 16 => "Failed", ...> 32 => "Archived", ...> 64 => "Ready to Archive", ...> 128 => "Ready to Publish", ...> } iex> BitFlags.to_string(100, descriptions) "Completed, Archived, Ready to Archive"

unset(target, flag)

Description

Returns the bitwise AND of two flags. In other words, it unsets the bit that corresopnds to the flag

  • GIVEN: original_state is 0b01100100 (integer: 100)
  • WHEN the flag to be unset is 0b01000000 (integer: 64)
  • THEN the result is 0b00100100 (integer: 36)

Parameters

- `target`: the integer representation of the state
- `flag`  : the integer representation of the flag

Output

The integer representation of the state after unsetting the flag

Examples

iex> BitFlags.unset(100, 64)
36

unset_all(target, flags)

Returns the bitwise AND of multiple flags against a given state. In other words, it unsets the bits that corresopnds to the flags GIVEN: original_state is 0b11100100 (integer: 228) WHEN the flags to be unset are [0b01000000, 0b10000000] (integers: 64, 128) THEN the result is 0b00100100 (integer: 36)

Example: iex> BitFlags.unset_all(228, [64, 128]) 36