class Puppet::Pops::Types::StringConverter

Converts Puppet runtime objects to String under the control of a Format. Use from Puppet Language is via the function `new`.

@api private

Constants

DEFAULT_ARRAY_DELIMITERS
DEFAULT_ARRAY_FORMAT
DEFAULT_CONTAINER_FORMATS

format used by default for values in a container (basically strings are quoted since they may contain a ','))

DEFAULT_HASH_DELIMITERS
DEFAULT_HASH_FORMAT
DEFAULT_INDENTATION
DEFAULT_PARAMETER_FORMAT
DEFAULT_STRING_FORMATS
FMT_KEYS

Public Class Methods

convert(value, string_formats = :default) click to toggle source

@api public

    # File lib/puppet/pops/types/string_converter.rb
246 def self.convert(value, string_formats = :default)
247   singleton.convert(value, string_formats)
248 end
new() click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
252 def initialize
253   @string_visitor = Visitor.new(self, "string", 3, 3)
254 end

Public Instance Methods

convert(value, string_formats = :default) click to toggle source

Converts the given value to a String, under the direction of formatting rules per type.

When converting to string it is possible to use a set of built in conversion rules.

A format is specified on the form:

´´´ %[Flags][.Precision]Format ´´´

`Width` is the number of characters into which the value should be fitted. This allocated space is padded if value is shorter. By default it is space padded, and the flag 0 will cause padding with 0 for numerical formats.

`Precision` is the number of fractional digits to show for floating point, and the maximum characters included in a string format.

Note that all data type supports the formats `s` and `p` with the meaning “default to-string” and “default-programmatic to-string”.

### Integer

| Format | Integer Formats | —— | ————— | d | Decimal, negative values produces leading '-' | x X | Hexadecimal in lower or upper case. Uses ..f/..F for negative values unless # is also used | o | Octal. Uses ..0 for negative values unless # is also used | b B | Binary with prefix 'b' or 'B'. Uses ..1/..1 for negative values unless # is also used | c | numeric value representing a Unicode value, result is a one unicode character string, quoted if alternative flag # is used | s | same as d, or d in quotes if alternative flag # is used | p | same as d | eEfgGaA | converts integer to float and formats using the floating point rules

Defaults to `d`

### Float

| Format | Float formats | —— | ————- | f | floating point in non exponential notation | e E | exponential notation with 'e' or 'E' | g G | conditional exponential with 'e' or 'E' if exponent < -4 or >= the precision | a A | hexadecimal exponential form, using 'x'/'X' as prefix and 'p'/'P' before exponent | s | converted to string using format p, then applying string formatting rule, alternate form # quotes result | p | f format with minimum significant number of fractional digits, prec has no effect | dxXobBc | converts float to integer and formats using the integer rules

Defaults to `p`

### String

| Format | String | —— | —— | s | unquoted string, verbatim output of control chars | p | programmatic representation - strings are quoted, interior quotes and control chars are escaped

| C | each

name segment capitalized, quoted if alternative flag # is used

| c | capitalized string, quoted if alternative flag # is used | d | downcased string, quoted if alternative flag # is used | u | upcased string, quoted if alternative flag # is used | t | trims leading and trailing whitespace from the string, quoted if alternative flag # is used

Defaults to `s` at top level and `p` inside array or hash.

### Boolean

| Format | Boolean Formats | —- | ——————- | t T | 'true'/'false' or 'True'/'False' , first char if alternate form is used (i.e. 't'/'f' or 'T'/'F'). | y Y | 'yes'/'no', 'Yes'/'No', 'y'/'n' or 'Y'/'N' if alternative flag # is used | dxXobB | numeric value 0/1 in accordance with the given format which must be valid integer format | eEfgGaA | numeric value 0.0/1.0 in accordance with the given float format and flags | s | 'true' / 'false' | p | 'true' / 'false'

### Regexp

| Format | Regexp Formats (%/) | —- | —————— | s | / / delimiters, alternate flag replaces / delimiters with quotes | p | / / delimiters

### Undef

| Format | Undef formats | —— | ————- | s | empty string, or quoted empty string if alternative flag # is used | p | 'undef', or quoted '“undef”' if alternative flag # is used | n | 'nil', or 'null' if alternative flag # is used | dxXobB | 'NaN' | eEfgGaA | 'NaN' | v | 'n/a' | V | 'N/A' | u | 'undef', or 'undefined' if alternative # flag is used

### Default (value)

| Format | Default formats | —— | ————— | d D | 'default' or 'Default', alternative form # causes value to be quoted | s | same as d | p | same as d

### Binary (value)

| Format | Default formats | —— | ————— | s | binary as unquoted characters | p | 'Binary(“<base64strict>”)' | b | '<base64>' - base64 string with newlines inserted | B | '<base64strict>' - base64 strict string (without newlines inserted) | u | '<base64urlsafe>' - base64 urlsafe string | t | 'Binary' - outputs the name of the type only | T | 'BINARY' - output the name of the type in all caps only

The alternate form flag `#` will quote the binary or base64 text output The width and precision values are applied to the text part only in `%p` format.

### Array & Tuple

| Format | Array/Tuple Formats | —— | ————- | a | formats with `[ ]` delimiters and `,`, alternate form `#` indents nested arrays/hashes | s | same as a | p | same as a

See “Flags” `<[({|` for formatting of delimiters, and “Additional parameters for containers; Array and Hash” for more information about options.

The alternate form flag `#` will cause indentation of nested array or hash containers. If width is also set it is taken as the maximum allowed length of a sequence of elements (not including delimiters). If this max length is exceeded, each element will be indented.

### Hash & Struct

| Format | Hash/Struct Formats | —— | ————- | h | formats with `{ }` delimiters, `,` element separator and ` => ` inner element separator unless overridden by flags | s | same as h | p | same as h | a | converts the hash to an array of [k,v] tuples and formats it using array rule(s)

See “Flags” `<[({|` for formatting of delimiters, and “Additional parameters for containers; Array and Hash” for more information about options.

The alternate form flag `#` will format each hash key/value entry indented on a separate line.

### Type

| Format | Array/Tuple Formats | —— | ————- | s | The same as p, quoted if alternative flag # is used | p | Outputs the type in string form as specified by the Puppet Language

### Flags

| Flag | Effect | —— | —— | (space) | space instead of + for numeric output (- is shown), for containers skips delimiters | # | alternate format; prefix 0x/0x, 0 (octal) and 0b/0B for binary, Floats force decimal '.'. For g/G keep trailing 0. | + | show sign +/- depending on value's sign, changes x,X, o,b, B format to not use 2's complement form | - | left justify the value in the given width | 0 | pad with 0 instead of space for widths larger than value | <[({| | defines an enclosing pair <> [] () {} or | | when used with a container type

### Additional parameters for containers; Array and Hash

For containers (Array and Hash), the format is specified by a hash where the following keys can be set:

  • `'format'` - the format specifier for the container itself

  • `'separator'` - the separator string to use between elements, should not contain padding space at the end

  • `'separator2'` - the separator string to use between association of hash entries key/value

  • `'string_formats'´ - a map of type to format for elements contained in the container

Note that the top level format applies to Array and Hash objects contained/nested in an Array or a Hash.

Given format mappings are merged with (default) formats and a format specified for a narrower type wins over a broader.

@param mode [String, Symbol] :strict or :extended (or :default which is the same as :strict) @param string_formats [String, Hash] format tring, or a hash mapping type to a format string, and for Array and Hash types map to hash of details

    # File lib/puppet/pops/types/string_converter.rb
479 def convert(value, string_formats = :default)
480   options = DEFAULT_STRING_FORMATS
481 
482   value_type = TypeCalculator.infer_set(value)
483   if string_formats.is_a?(String)
484     # For Array and Hash, the format is given as a Hash where 'format' key is the format for the collection itself
485     if Puppet::Pops::Types::PArrayType::DEFAULT.assignable?(value_type)
486       # add the format given for the exact type
487       string_formats = { Puppet::Pops::Types::PArrayType::DEFAULT => {'format' => string_formats }}
488     elsif Puppet::Pops::Types::PHashType::DEFAULT.assignable?(value_type)
489         # add the format given for the exact type
490         string_formats = { Puppet::Pops::Types::PHashType::DEFAULT => {'format' => string_formats }}
491     else
492       # add the format given for the exact type
493       string_formats = { value_type => string_formats }
494     end
495   end
496 
497   case string_formats
498   when :default
499    # do nothing, use default formats
500 
501   when Hash
502     # Convert and validate user input
503     string_formats = validate_input(string_formats)
504     # Merge user given with defaults such that user options wins, merge is deep and format specific
505     options = Format.merge_string_formats(DEFAULT_STRING_FORMATS, string_formats)
506   else
507     raise ArgumentError, "string conversion expects a Default value or a Hash of type to format mappings, got a '#{string_formats.class}'"
508   end
509 
510   _convert(value_type, value, options, DEFAULT_INDENTATION)
511 end
is_a_or_h?(x) click to toggle source
     # File lib/puppet/pops/types/string_converter.rb
1009 def is_a_or_h?(x)
1010   x.is_a?(Array) || x.is_a?(Hash)
1011 end
is_container?(t) click to toggle source
     # File lib/puppet/pops/types/string_converter.rb
1013 def is_container?(t)
1014   case t
1015   when PArrayType, PHashType, PStructType, PTupleType, PObjectType
1016     true
1017   else
1018     false
1019   end
1020 end
puppet_double_quote(str) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
885 def puppet_double_quote(str)
886   bld = '"'
887   str.each_codepoint do |codepoint|
888     case codepoint
889     when 0x09
890       bld << '\\t'
891     when 0x0a
892       bld << '\\n'
893     when 0x0d
894       bld << '\\r'
895     when 0x22
896       bld << '\\"'
897     when 0x24
898       bld << '\\$'
899     when 0x5c
900       bld << '\\\\'
901     else
902       if codepoint < 0x20
903         bld << sprintf('\\u{%X}', codepoint)
904       elsif codepoint <= 0x7f
905         bld << codepoint
906       else
907         bld << [codepoint].pack('U')
908       end
909     end
910   end
911   bld << '"'
912   bld
913 end
puppet_quote(str, enforce_double_quotes = false) click to toggle source

Performs a '%p' formatting of the given str such that the output conforms to Puppet syntax. An ascii string without control characters, dollar, single-qoute, or backslash, will be quoted using single quotes. All other strings will be quoted using double quotes.

@param [String] str the string that should be formatted @param [Boolean] enforce_double_quotes if true the result will be double quoted (even if single quotes would be possible) @return [String] the formatted string

@api public

    # File lib/puppet/pops/types/string_converter.rb
849 def puppet_quote(str, enforce_double_quotes = false)
850   if enforce_double_quotes
851     return puppet_double_quote(str)
852   end
853 
854   # Assume that the string can be single quoted
855   bld = '\''
856   bld.force_encoding(str.encoding)
857   escaped = false
858   str.each_codepoint do |codepoint|
859     # Control characters and non-ascii characters cannot be present in a single quoted string
860     return puppet_double_quote(str) if codepoint < 0x20
861 
862     if escaped
863       bld << 0x5c << codepoint
864       escaped = false
865     else
866       if codepoint == 0x27
867         bld << 0x5c << codepoint
868       elsif codepoint == 0x5c
869         escaped = true
870       elsif codepoint <= 0x7f
871         bld << codepoint
872       else
873         bld << [codepoint].pack('U')
874       end
875     end
876   end
877 
878   # If string ended with a backslash, then that backslash must be escaped
879   bld << 0x5c if escaped
880 
881   bld << '\''
882   bld
883 end
string_PAnyType(val_type, val, format_map, _) click to toggle source

Basically string_PAnyType converts the value to a String and then formats it according to the resulting type

@api private

    # File lib/puppet/pops/types/string_converter.rb
613 def string_PAnyType(val_type, val, format_map, _)
614   f = get_format(val_type, format_map)
615   Kernel.format(f.orig_fmt, val)
616 end
string_PArrayType(val_type, val, format_map, indentation) click to toggle source
     # File lib/puppet/pops/types/string_converter.rb
 931 def string_PArrayType(val_type, val, format_map, indentation)
 932   format         = get_format(val_type, format_map)
 933   sep            = format.separator || DEFAULT_ARRAY_FORMAT.separator
 934   string_formats = format.container_string_formats || DEFAULT_CONTAINER_FORMATS
 935   delims         = format.delimiter_pair(DEFAULT_ARRAY_DELIMITERS)
 936 
 937   # Make indentation active, if array is in alternative format, or if nested in indenting
 938   indentation = indentation.indenting(format.alt? || indentation.is_indenting?)
 939 
 940   case format.format
 941   when :a, :s, :p
 942     buf = ''
 943     if indentation.breaks?
 944       buf << "\n"
 945       buf << indentation.padding
 946     end
 947     buf << delims[0]
 948 
 949     # Make a first pass to format each element
 950     children_indentation = indentation.increase(format.alt?) # tell children they are expected to indent
 951     mapped = val.map do |v|
 952       if children_indentation.first?
 953         children_indentation = children_indentation.subsequent
 954       end
 955       val_t = TypeCalculator.infer_set(v)
 956       _convert(val_t, v, is_container?(val_t) ? format_map : string_formats, children_indentation)
 957     end
 958 
 959     # compute widest run in the array, skip nested arrays and hashes
 960     # then if size > width, set flag if a break on each element should be performed
 961     if format.alt? && format.width
 962       widest = val.each_with_index.reduce([0]) do | memo, v_i |
 963         # array or hash breaks
 964         if is_a_or_h?(v_i[0])
 965           memo << 0
 966         else
 967           memo[-1] += mapped[v_i[1]].length
 968         end
 969         memo
 970       end
 971       widest = widest.max
 972       sz_break = widest > (format.width || Float::INFINITY)
 973     else
 974       sz_break = false
 975     end
 976 
 977     # output each element with breaks and padding
 978     children_indentation = indentation.increase(format.alt?)
 979     val.each_with_index do |v, i|
 980       str_val = mapped[i]
 981       if children_indentation.first?
 982         children_indentation = children_indentation.subsequent
 983         # if breaking, indent first element by one
 984         if sz_break && !is_a_or_h?(v)
 985           buf << ' '
 986         end
 987       else
 988         buf << sep
 989         # if break on each (and breaking will not occur because next is an array or hash)
 990         # or, if indenting, and previous was an array or hash, then break and continue on next line
 991         # indented.
 992         if (sz_break && !is_a_or_h?(v)) || (format.alt? && i > 0 && is_a_or_h?(val[i-1]) && !is_a_or_h?(v))
 993           buf.rstrip! unless buf[-1] == "\n"
 994           buf << "\n"
 995           buf << children_indentation.padding
 996         end
 997       end
 998       # remove trailing space added by separator if followed by break
 999       buf.rstrip! if buf[-1] == ' ' && str_val[0] == "\n"
1000       buf << str_val
1001     end
1002     buf << delims[1]
1003     buf
1004   else
1005     raise FormatError.new('Array', format.format, 'asp')
1006   end
1007 end
string_PBinaryType(val_type, val, format_map, _) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
760 def string_PBinaryType(val_type, val, format_map, _)
761   f = get_format(val_type, format_map)
762   substitute = f.alt? ? 'p' : 's'
763   case f.format
764   when :s
765     val_to_convert = val.binary_buffer
766     if !f.alt?
767       # Assume it is valid UTF-8
768       val_to_convert = val_to_convert.dup.force_encoding('UTF-8')
769       # If it isn't
770       unless val_to_convert.valid_encoding?
771         # try to convert and fail with details about what is wrong
772         val_to_convert = val.binary_buffer.encode('UTF-8')
773       end
774     else
775       val_to_convert = val.binary_buffer
776     end
777     Kernel.format(f.orig_fmt.gsub('s', substitute), val_to_convert)
778 
779   when :p
780     # width & precision applied to string, not the the name of the type
781     "Binary(\"#{Kernel.format(f.orig_fmt.tr('p', 's'), val.to_s)}\")"
782 
783   when :b
784     Kernel.format(f.orig_fmt.gsub('b', substitute), val.relaxed_to_s)
785 
786   when :B
787     Kernel.format(f.orig_fmt.gsub('B', substitute), val.to_s)
788 
789   when :u
790     Kernel.format(f.orig_fmt.gsub('u', substitute), val.urlsafe_to_s)
791 
792   when :t
793     # Output as the type without any data
794     Kernel.format(f.orig_fmt.gsub('t', substitute), 'Binary')
795 
796   when :T
797     # Output as the type without any data in all caps
798     Kernel.format(f.orig_fmt.gsub('T', substitute), 'BINARY')
799 
800   else
801     raise FormatError.new('Binary', f.format, 'bButTsp')
802   end
803 end
string_PBooleanType(val_type, val, format_map, indentation) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
654 def string_PBooleanType(val_type, val, format_map, indentation)
655   f = get_format(val_type, format_map)
656   case f.format
657   when :t
658     # 'true'/'false' or 't'/'f' if in alt mode
659     str_bool = val.to_s
660     apply_string_flags(f, f.alt? ? str_bool[0] : str_bool)
661 
662   when :T
663     # 'True'/'False' or 'T'/'F' if in alt mode
664     str_bool = val.to_s.capitalize
665     apply_string_flags(f, f.alt? ? str_bool[0] : str_bool)
666 
667   when :y
668     # 'yes'/'no' or 'y'/'n' if in alt mode
669     str_bool = val ? 'yes' : 'no'
670     apply_string_flags(f, f.alt? ? str_bool[0] : str_bool)
671 
672   when :Y
673     # 'Yes'/'No' or 'Y'/'N' if in alt mode
674     str_bool = val ? 'Yes' : 'No'
675     apply_string_flags(f, f.alt? ? str_bool[0] : str_bool)
676 
677   when :d, :x, :X, :o, :b, :B
678     # Boolean in numeric form, formated by integer rule
679     numeric_bool = val ? 1 : 0
680     string_formats = { Puppet::Pops::Types::PIntegerType::DEFAULT => f}
681     _convert(TypeCalculator.infer_set(numeric_bool), numeric_bool, string_formats, indentation)
682 
683   when :e, :E, :f, :g, :G, :a, :A
684     # Boolean in numeric form, formated by float rule
685     numeric_bool = val ? 1.0 : 0.0
686     string_formats = { Puppet::Pops::Types::PFloatType::DEFAULT => f}
687     _convert(TypeCalculator.infer_set(numeric_bool), numeric_bool, string_formats, indentation)
688 
689   when :s
690     apply_string_flags(f, val.to_s)
691 
692   when :p
693     apply_string_flags(f, val.inspect)
694 
695   else
696     raise FormatError.new('Boolean', f.format, 'tTyYdxXobBeEfgGaAsp')
697   end
698 end
string_PDefaultType(val_type, val, format_map, _) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
618 def string_PDefaultType(val_type, val, format_map, _)
619   f = get_format(val_type, format_map)
620   apply_string_flags(f, case f.format
621   when :d, :s, :p
622     f.alt? ? '"default"' : 'default'
623   when :D
624     f.alt? ? '"Default"' : 'Default'
625   else
626     raise FormatError.new('Default', f.format, 'dDsp')
627   end)
628 end
string_PFloatType(val_type, val, format_map, _) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
741 def string_PFloatType(val_type, val, format_map, _)
742   f = get_format(val_type, format_map)
743   case f.format
744   when :d, :x, :X, :o, :b, :B
745     Kernel.format(f.orig_fmt, val.to_i)
746 
747   when :e, :E, :f, :g, :G, :a, :A, :p
748     Kernel.format(f.orig_fmt, val)
749 
750   when :s
751     float_str = f.alt? ? "\"#{Kernel.format('%p', val)}\"" : Kernel.format('%p', val)
752     Kernel.format(f.orig_fmt, float_str)
753 
754   else
755     raise FormatError.new('Float', f.format, 'dxXobBeEfgGaAsp')
756   end
757 end
string_PHashType(val_type, val, format_map, indentation) click to toggle source

@api private

     # File lib/puppet/pops/types/string_converter.rb
1034 def string_PHashType(val_type, val, format_map, indentation)
1035   format         = get_format(val_type, format_map)
1036   sep            = format.separator  || DEFAULT_HASH_FORMAT.separator
1037   assoc          = format.separator2 || DEFAULT_HASH_FORMAT.separator2
1038   string_formats = format.container_string_formats || DEFAULT_CONTAINER_FORMATS
1039   delims         = format.delimiter_pair(DEFAULT_HASH_DELIMITERS)
1040 
1041   if format.alt? 
1042     sep = sep.rstrip unless sep[-1] == "\n"
1043     sep = "#{sep}\n"
1044   end
1045 
1046   cond_break     = ''
1047   padding        = ''
1048 
1049   case format.format
1050   when :a
1051     # Convert to array and use array rules
1052     array_hash = val.to_a
1053     _convert(TypeCalculator.infer_set(array_hash), array_hash, format_map, indentation)
1054 
1055   when :h, :s, :p
1056     indentation = indentation.indenting(format.alt? || indentation.is_indenting?)
1057     buf = ''
1058     if indentation.breaks?
1059       buf << "\n"
1060       buf << indentation.padding
1061     end
1062 
1063     children_indentation = indentation.increase
1064     if format.alt?
1065       cond_break = "\n"
1066       padding = children_indentation.padding
1067     end
1068     buf << delims[0]
1069     buf << cond_break  # break after opening delimiter if pretty printing
1070     buf << val.map do |k,v|
1071       key_type = TypeCalculator.infer_set(k)
1072       val_type = TypeCalculator.infer_set(v)
1073       key = _convert(key_type, k, is_container?(key_type) ? format_map : string_formats, children_indentation)
1074       val = _convert(val_type, v, is_container?(val_type) ? format_map : string_formats, children_indentation)
1075       "#{padding}#{key}#{assoc}#{val}"
1076     end.join(sep)
1077     if format.alt?
1078       buf << cond_break
1079       buf << indentation.padding
1080     end
1081     buf << delims[1]
1082     buf
1083   else
1084     raise FormatError.new('Hash', format.format, 'hasp')
1085   end
1086 end
string_PIntegerType(val_type, val, format_map, _) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
716 def string_PIntegerType(val_type, val, format_map, _)
717   f = get_format(val_type, format_map)
718   case f.format
719   when :d, :x, :X, :o, :b, :B, :p
720     Kernel.format(f.orig_fmt, val)
721 
722   when :e, :E, :f, :g, :G, :a, :A
723     Kernel.format(f.orig_fmt, val.to_f)
724 
725   when :c
726     char = [val].pack("U")
727     char = f.alt? ? "\"#{char}\"" : char
728     Kernel.format(f.orig_fmt.tr('c','s'), char)
729 
730   when :s
731     fmt = f.alt? ? 'p' : 's'
732     int_str = Kernel.format('%d', val)
733     Kernel.format(f.orig_fmt.gsub('s', fmt), int_str)
734 
735   else
736     raise FormatError.new('Integer', f.format, 'dxXobBeEfgGaAspc')
737   end
738 end
string_PIteratorType(val_type, val, format_map, indentation) click to toggle source

@api private

     # File lib/puppet/pops/types/string_converter.rb
1028 def string_PIteratorType(val_type, val, format_map, indentation)
1029   v = val.to_a
1030   _convert(TypeCalculator.infer_set(v), v, format_map, indentation)
1031 end
string_PObjectType(val_type, val, format_map, indentation) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
561 def string_PObjectType(val_type, val, format_map, indentation)
562   f = get_format(val_type, format_map)
563   case f.format
564   when :p
565     fmt = TypeFormatter.singleton
566     indentation = indentation.indenting(f.alt? || indentation.is_indenting?)
567     fmt = fmt.indented(indentation.level, 2) if indentation.is_indenting?
568     fmt.string(val)
569   when :s
570     val.to_s
571   when :q
572     val.inspect
573   else
574     raise FormatError.new('Object', f.format, 'spq')
575   end
576 end
string_PObjectTypeExtension(val_type, val, format_map, indentation) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
578 def string_PObjectTypeExtension(val_type, val, format_map, indentation)
579   string_PObjectType(val_type.base_type, val, format_map, indentation)
580 end
string_PRegexpType(val_type, val, format_map, _) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
916 def string_PRegexpType(val_type, val, format_map, _)
917   f = get_format(val_type, format_map)
918   case f.format
919   when :p
920     str_regexp = PRegexpType.regexp_to_s_with_delimiters(val)
921     f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.tr('p', 's'), str_regexp)
922   when :s
923     str_regexp = PRegexpType.regexp_to_s(val)
924     str_regexp = puppet_quote(str_regexp) if f.alt?
925     f.orig_fmt == '%s' ? str_regexp : Kernel.format(f.orig_fmt, str_regexp)
926   else
927     raise FormatError.new('Regexp', f.format, 'sp')
928   end
929 end
string_PRuntimeType(val_type, val, format_map, indent) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
582 def string_PRuntimeType(val_type, val, format_map, indent)
583   # Before giving up on this, and use a string representation of the unknown
584   # object, a check is made to see if the object can present itself as
585   # a hash or an array. If it can, then that representation is used instead.
586   if val.is_a?(Hash)
587     hash = val.to_hash
588     # Ensure that the returned value isn't derived from Hash
589     return string_PHashType(val_type, hash, format_map, indent) if hash.instance_of?(Hash)
590   elsif val.is_a?(Array)
591     array = val.to_a
592     # Ensure that the returned value isn't derived from Array
593     return string_PArrayType(val_type, array, format_map, indent) if array.instance_of?(Array)
594   end
595 
596   f = get_format(val_type, format_map)
597   case f.format
598   when :s
599     val.to_s
600   when :p
601     puppet_quote(val.to_s)
602   when :q
603     val.inspect
604   else
605     raise FormatError.new('Runtime', f.format, 'spq')
606   end
607 end
string_PStringType(val_type, val, format_map, _) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
806 def string_PStringType(val_type, val, format_map, _)
807   f = get_format(val_type, format_map)
808   case f.format
809   when :s
810     Kernel.format(f.orig_fmt, val)
811 
812   when :p
813     apply_string_flags(f, puppet_quote(val, f.alt?))
814 
815   when :c
816     c_val = val.capitalize
817     f.alt? ? apply_string_flags(f, puppet_quote(c_val)) :  Kernel.format(f.orig_fmt.tr('c', 's'), c_val)
818 
819   when :C
820     c_val = val.split('::').map {|s| s.capitalize }.join('::')
821     f.alt? ? apply_string_flags(f, puppet_quote(c_val)) :  Kernel.format(f.orig_fmt.tr('C', 's'), c_val)
822 
823   when :u
824     c_val = val.upcase
825     f.alt? ? apply_string_flags(f, puppet_quote(c_val)) :  Kernel.format(f.orig_fmt.tr('u', 's'), c_val)
826 
827   when :d
828     c_val = val.downcase
829     f.alt? ? apply_string_flags(f, puppet_quote(c_val)) :  Kernel.format(f.orig_fmt.tr('d', 's'), c_val)
830 
831   when :t  # trim
832     c_val = val.strip
833     f.alt? ? apply_string_flags(f, puppet_quote(c_val)) :  Kernel.format(f.orig_fmt.tr('t', 's'), c_val)
834 
835   else
836     raise FormatError.new('String', f.format, 'cCudspt')
837   end
838 end
string_PStructType(val_type, val, format_map, indentation) click to toggle source

@api private

     # File lib/puppet/pops/types/string_converter.rb
1089 def string_PStructType(val_type, val, format_map, indentation)
1090   string_PHashType(val_type, val, format_map, indentation)
1091 end
string_PTupleType(val_type, val, format_map, indentation) click to toggle source

@api private

     # File lib/puppet/pops/types/string_converter.rb
1023 def string_PTupleType(val_type, val, format_map, indentation)
1024   string_PArrayType(val_type, val, format_map, indentation)
1025 end
string_PTypeType(val_type, val, format_map, _) click to toggle source

@api private

     # File lib/puppet/pops/types/string_converter.rb
1094 def string_PTypeType(val_type, val, format_map, _)
1095   f = get_format(val_type, format_map)
1096   case f.format
1097   when :s
1098     str_val = f.alt? ? "\"#{val}\"" : val.to_s
1099     Kernel.format(f.orig_fmt, str_val)
1100   when :p
1101     Kernel.format(f.orig_fmt.tr('p', 's'), val.to_s)
1102   else
1103     raise FormatError.new('Type', f.format, 'sp')
1104   end
1105 end
string_PURIType(val_type, val, format_map, indentation) click to toggle source

@api private

     # File lib/puppet/pops/types/string_converter.rb
1108 def string_PURIType(val_type, val, format_map, indentation)
1109   f = get_format(val_type, format_map)
1110   case f.format
1111   when :p
1112     fmt = TypeFormatter.singleton
1113     indentation = indentation.indenting(f.alt? || indentation.is_indenting?)
1114     fmt = fmt.indented(indentation.level, 2) if indentation.is_indenting?
1115     fmt.string(val)
1116   when :s
1117     str_val = val.to_s
1118     Kernel.format(f.orig_fmt, f.alt? ? puppet_quote(str_val) : str_val)
1119   else
1120     raise FormatError.new('URI', f.format, 'sp')
1121   end
1122 end
string_PUndefType(val_type, val, format_map, _) click to toggle source

@api private

    # File lib/puppet/pops/types/string_converter.rb
631 def string_PUndefType(val_type, val, format_map, _)
632   f = get_format(val_type, format_map)
633   apply_string_flags(f, case f.format
634   when :n
635     f.alt? ? 'null' : 'nil'
636   when :u
637     f.alt? ? 'undefined' : 'undef'
638   when :d, :x, :X, :o, :b, :B, :e, :E, :f, :g, :G, :a, :A
639     'NaN'
640   when :v
641     'n/a'
642   when :V
643     'N/A'
644   when :s
645     f.alt? ? '""' : ''
646   when :p
647     f.alt? ? '"undef"' : 'undef'
648   else
649     raise FormatError.new('Undef', f.format, 'nudxXobBeEfgGaAvVsp')
650   end)
651 end

Private Instance Methods

_convert(val_type, value, format_map, indentation) click to toggle source

# A method only used for manual debugging as the default output of the formatting rules is # very hard to read otherwise. # # @api private def dump_string_formats(f, indent = 1)

return f.to_s unless f.is_a?(Hash)
"{#{f.map {|k,v| "#{k.to_s} => #{dump_string_formats(v,indent+1)}"}.join(",\n#{'  '*indent}  ")}}"

end

    # File lib/puppet/pops/types/string_converter.rb
522 def _convert(val_type, value, format_map, indentation)
523   @string_visitor.visit_this_3(self, val_type, value, format_map, indentation)
524 end
apply_string_flags(f, literal_str) click to toggle source

Performs post-processing of literals to apply width and precision flags

    # File lib/puppet/pops/types/string_converter.rb
701 def apply_string_flags(f, literal_str)
702   if f.left || f.width || f.prec
703     fmt = '%'
704     fmt << '-' if f.left
705     fmt << f.width.to_s if f.width
706     fmt << '.' << f.prec.to_s if f.prec
707     fmt << 's'
708     Kernel.format(fmt, literal_str)
709   else
710     literal_str
711   end
712 end
get_format(val_t, format_options) click to toggle source

Maps the inferred type of o to a formatting rule

     # File lib/puppet/pops/types/string_converter.rb
1125 def get_format(val_t, format_options)
1126   fmt = format_options.find {|k,_| k.assignable?(val_t) }
1127   return fmt[1] unless fmt.nil?
1128   return Format.new("%s")
1129 end
validate_container_input(fmt) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
549 def validate_container_input(fmt)
550   if (fmt.keys - FMT_KEYS).size > 0
551     raise ArgumentError, "only #{FMT_KEYS.map {|k| "'#{k}'"}.join(', ')} are allowed in a container format, got #{fmt}"
552   end
553   result                          = Format.new(fmt['format'])
554   result.separator                = fmt['separator']
555   result.separator2               = fmt['separator2']
556   result.container_string_formats = validate_input(fmt['string_formats'])
557   result
558 end
validate_input(fmt) click to toggle source
    # File lib/puppet/pops/types/string_converter.rb
527 def validate_input(fmt)
528   return nil if fmt.nil?
529   unless fmt.is_a?(Hash)
530     raise ArgumentError, "expected a hash with type to format mappings, got instance of '#{fmt.class}'"
531   end
532   fmt.reduce({}) do | result, entry|
533     key, value = entry
534     unless key.is_a?(Types::PAnyType)
535       raise ArgumentError, "top level keys in the format hash must be data types, got instance of '#{key.class}'"
536     end
537     if value.is_a?(Hash)
538       result[key] = validate_container_input(value)
539     else
540       result[key] = Format.new(value)
541     end
542     result
543   end
544 end