Class: Versionomy::Format::Delimiter::RecognizerBase

Inherits:
Object
  • Object
show all
Defined in:
lib/versionomy/format/delimiter.rb

Overview

A recognizer handles both parsing and unparsing of a particular kind of syntax. During parsing, it recognizes the syntax based on regular expressions for the delimiters and the value. If the string matches the syntax recognized by this object, an appropriate value and style are returned. During unparsing, the should_unparse? method should be called first to determine whether this object is responsible for unparsing the given value and style. If should_unparse? returns true, the unparse method should be called to actually generate a a string fragment, or return nil if the field is determined to be optional in the unparsed string.

This is a base class. The actual classes should implement initialize, parsed_value, and unparsed_value, and may optionally override the should_unparse? method.

Direct Known Subclasses

AlphabeticIntegerRecognizer, BasicIntegerRecognizer, MappingSymbolRecognizer, RegexpStringRecognizer, RegexpSymbolRecognizer

Instance Method Summary (collapse)

Instance Method Details

- (Object) parse(parse_state_, parse_params_)

Attempt to parse the field from the string if the syntax matches this recognizer's configuration. Returns either nil, indicating that this recognizer doesn't match the given syntax, or a two element array of the value and style.



788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
# File 'lib/versionomy/format/delimiter.rb', line 788

def parse(parse_state_, parse_params_)
  return nil if @requires_previous_field && parse_state_[:previous_field_missing]
  string_ = parse_state_[:string]
  if @delimiter_regexp
    match_ = @delimiter_regexp.match(string_)
    return nil unless match_
    delim_ = match_[0]
    string_ = match_.post_match
  else
    delim_ = ''
  end
  match_ = @value_regexp.match(string_)
  return nil unless match_
  value_ = match_[0]
  string_ = match_.post_match
  if @post_delimiter_regexp
    match_ = @post_delimiter_regexp.match(string_)
    return nil unless match_
    post_delim_ = match_[0]
    string_ = match_.post_match
  else
    post_delim_ = nil
  end
  if @follower_regexp
    match_ = @follower_regexp.match(string_)
    return nil unless match_
  end
  parse_result_ = parsed_value(value_, parse_params_)
  return nil unless parse_result_
  unparse_params_ = parse_result_[1] || {}
  if delim_ != @default_delimiter
    unparse_params_[@delim_unparse_param_key] = delim_
  end
  if post_delim_ && post_delim_ != @default_post_delimiter
    unparse_params_[@post_delim_unparse_param_key] = post_delim_
  end
  unparse_params_[@required_unparse_param_key] = true if @default_value_optional
  [parse_result_[0], @style, string_, unparse_params_]
end

- (Object) requires_next_field

Returns true if this field can appear in an unparsed string only if the next field also appears.



832
833
834
# File 'lib/versionomy/format/delimiter.rb', line 832

def requires_next_field
  @requires_next_field
end

- (Object) setup(field_, value_regexp_, opts_)

Derived classes should call this from their initialize method to set up the recognizer's basic parameters.



758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/versionomy/format/delimiter.rb', line 758

def setup(field_, value_regexp_, opts_)
  @style = opts_[:style]
  @default_value_optional = opts_[:default_value_optional]
  @default_value = opts_[:default_value] || field_.default_value
  @regexp_options = opts_[:case_sensitive] ? nil : ::Regexp::IGNORECASE
  @value_regexp = ::Regexp.new("\\A(#{value_regexp_})", @regexp_options)
  regexp_ = opts_[:delimiter_regexp] || '\.'
  @delimiter_regexp = regexp_.length > 0 ? ::Regexp.new("\\A(#{regexp_})", @regexp_options) : nil
  @full_delimiter_regexp = regexp_.length > 0 ? ::Regexp.new("\\A(#{regexp_})\\z", @regexp_options) : nil
  regexp_ = opts_[:post_delimiter_regexp] || ''
  @post_delimiter_regexp = regexp_.length > 0 ? ::Regexp.new("\\A(#{regexp_})", @regexp_options) : nil
  @full_post_delimiter_regexp = regexp_.length > 0 ? ::Regexp.new("\\A(#{regexp_})\\z", @regexp_options) : nil
  regexp_ = opts_[:expected_follower_regexp] || ''
  @follower_regexp = regexp_.length > 0 ? ::Regexp.new("\\A(#{regexp_})", @regexp_options) : nil
  @default_delimiter = opts_[:default_delimiter] || '.'
  @default_post_delimiter = opts_[:default_post_delimiter] || ''
  @requires_previous_field = opts_.fetch(:requires_previous_field, true)
  @requires_next_field = opts_.fetch(:requires_next_field, false)
  name_ = field_.name
  @delim_unparse_param_key = "#{name_}_delim".to_sym
  @post_delim_unparse_param_key = "#{name_}_postdelim".to_sym
  @required_unparse_param_key = "#{name_}_required".to_sym
end

- (Boolean) should_unparse?(value_, style_)

Returns true if this recognizer should be used to unparse the given value and style.

Returns:

  • (Boolean)


840
841
842
# File 'lib/versionomy/format/delimiter.rb', line 840

def should_unparse?(value_, style_)
  style_ == @style
end

- (Object) unparse(value_, style_, unparse_params_, required_for_later_)

Unparse the given value in the given style, and return a string fragment, or nil if the field is determined to be "optional" to unparse and isn't otherwise required (because a later field needs it to be present, for example).

It is guaranteed that this will be called only if should_unparse? returns true.



853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
# File 'lib/versionomy/format/delimiter.rb', line 853

def unparse(value_, style_, unparse_params_, required_for_later_)
  str_ = nil
  if !@default_value_optional || value_ != @default_value ||
      required_for_later_ || unparse_params_[@required_unparse_param_key]
  then
    str_ = unparsed_value(value_, style_, unparse_params_)
    if str_
      if !@full_delimiter_regexp
        delim_ = ''
      else
        delim_ = unparse_params_[@delim_unparse_param_key] || @default_delimiter
        if @full_delimiter_regexp !~ delim_
          delim_ = @default_delimiter
        end
      end
      if !@full_post_delimiter_regexp
        post_delim_ = ''
      else
        post_delim_ = unparse_params_[@post_delim_unparse_param_key] || @default_post_delimiter
        if @full_post_delimiter_regexp !~ post_delim_
          post_delim_ = @default_post_delimiter
        end
      end
      str_ = delim_ + str_ + post_delim_
    end
    str_
  else
    nil
  end
end