package DX::SetOver;

use DX::ArrayStream;
use Moo;

has over => (is => 'ro', required => 1);

has values => (is => 'ro', default => sub { {} });

sub key_list { sort keys %{$_[0]->values} }

sub get {
  my ($self, $key) = @_;
  return $self->values->{$key};
}

sub to_stream {
  my ($self) = @_;
  my $values = $self->values;
  return DX::ArrayStream->from_array(@{$values}{sort keys %$values});
}

sub with_value {
  my ($self, $value) = @_;
  return ref($self)->new(%$self, values => { %{$self->values} })
                   ->set_value($value);
}

sub set_value {
  my ($self, $value) = @_;
  $self->values->{$value->${\$self->over}} = $value;
  return $self;
}

sub remove_value {
  my ($self, $value) = @_;
  delete $self->values->{$value->${\$self->over}};
  return $self;
}

1;
