class RemiLib::RSConf::Builder

Overview

The Builder class is used to incrementally generate properly-formatted RSConf data.

require "libremiliacr"
alias RSConf = RemiLib::RSConf

str = RSConf::Builder.build do |builder|
  rs.writePair("foo", 69)
  rs.writePair("bar", true)
  rs.writePair("baz", "lol")
end

puts str

Defined in:

remilib/rsconf/builder.cr

Constructors

Class Method Summary

Instance Method Summary

Instance methods inherited from class Object

toRsconf(io : IO, *, indentSize : Int = 2, alwaysQuoteKeys : Bool = false, explicitRootObject : Bool = false, commaAfterValues : Bool = false, extraNewlineBetweenToplevelKeys : Bool = false) : Nil
toRsconf(*, indentSize : Int = 2, alwaysQuoteKeys : Bool = false, explicitRootObject : Bool = false, commaAfterValues : Bool = false, extraNewlineBetweenToplevelKeys : Bool = false) : String
toRsconf

Class methods inherited from class Object

fromRsconf(toplevel : RemiLib::RSConf::RSValue)
fromRsconf(data : String | IO | Path)
fromRsconf

Constructor Detail

def self.new(stream : IO, *, explicitRootObject : Bool = false) #

Creates a new Writer instance that will write data to stream.


[View source]

Class Method Detail

def self.build(io : IO, *, toplevelIsArray : Bool = false, explicitRootObject : Bool = false, noAutoToplevel : Bool = false, &) : Nil #

Creates a new Builder that will write to io and yields it to the block.

If noAutoToplevel is false, then #startToplevel is called before the yield happens to automatically start the toplevel value, and either #finishArray or #finishObject will be called after the yield returns. This basically automates the handling of the toplevel value. But, if noAutoToplevel is true, then none of this happens and you must start the toplevel yourself.

If toplevelIsArray is true, then #startToplevel will be called and told that the toplevel value is an array. You may then start writing array values. Ignored if noAutoToplevel is true.

If toplevelIsArray is false, then #startToplevel will be called and told that the toplevel value is an object. You may then start writing key/value pairs. Ignored if noAutoToplevel is true.

The explicitRootObject will set #explicitRootObject automatically before writing the root object. Ignored if noAutoToplevel is true.

# Write an array of values as RSConf data.
io = IO::Memory.new
RemiLib::RSConf::Builder.build(io, toplevelIsArray: true) do |rs|
  rs.writeBlockComment("This is a comment", 3)
  rs.writeValue("a")
  rs.writeValue("b")
  rs.writeValue("c")

  # We'll write an object as well.
  rs.writeObject do
    rs.writePair("Test", "lol")
    rs.writeComment("This is also a comment")
    rs.writePair("test2") do
      rs.writeArray do
        rs.writeValue("A").writeValue("B").writeValue("C")
        rs.writeValues("D", "E", "F")
      end
    end
  end

  # Lets' write a few more things.
  rs.writeArray("1", "2", "3")
  rs.writeObject({"a" => "1", "b" => "2"})
end

# Now `io` holds the RSConf data we wrote, so lets display it as a string.
puts io.to_s

[View source]
def self.build(*, toplevelIsArray : Bool = false, explicitRootObject : Bool = false, noAutoToplevel : Bool = false, &) : String #

Creates a new Builder and yields it to the block. This returns a string containing the written RSConf data.

If noAutoToplevel is false, then #startToplevel is called before the yield happens to automatically start the toplevel value, and either #finishArray or #finishObject will be called after the yield returns. This basically automates the handling of the toplevel value. But, if noAutoToplevel is true, then none of this happens and you must start the toplevel yourself.

If toplevelIsArray is true, then #startToplevel will be called and told that the toplevel value is an array. You may then start writing array values. Ignored if noAutoToplevel is true.

If toplevelIsArray is false, then #startToplevel will be called and told that the toplevel value is an object. You may then start writing key/value pairs. Ignored if noAutoToplevel is true.

The explicitRootObject will set #explicitRootObject automatically before writing the root object. Ignored if noAutoToplevel is true.

# Write an array of values as RSConf data.
str = RemiLib::RSConf::Builder.build(toplevelIsArray: true) do |rs|
  rs.writeBlockComment("This is a comment", 3)
  rs.writeValue("a")
  rs.writeValue("b")
  rs.writeValue("c")

  # We'll write an object as well.
  rs.writeObject do
    rs.writePair("Test", "lol")
    rs.writeComment("This is also a comment")
    rs.writePair("test2") do
      rs.writeArray do
        rs.writeValue("A").writeValue("B").writeValue("C")
        rs.writeValues("D", "E", "F")
      end
    end
  end

  # Lets' write a few more things.
  rs.writeArray("1", "2", "3")
  rs.writeObject({"a" => "1", "b" => "2"})
end

# Now str holds the RSConf data we wrote to a string.
puts str

[View source]

Instance Method Detail

def alwaysQuoteKeys=(alwaysQuoteKeys : Bool) #

When true, then key names are always quoted, even when they don't need to be. Otherwise they are only quoted when necessary.


[View source]
def alwaysQuoteKeys? : Bool #

When true, then key names are always quoted, even when they don't need to be. Otherwise they are only quoted when necessary.


[View source]
def alwaysUseScientificNotation=(alwaysUseScientificNotation : Bool) #

When true, then float values are always written using scientific notation.


[View source]
def alwaysUseScientificNotation? : Bool #

When true, then float values are always written using scientific notation.


[View source]
def commaAfterValues=(commaAfterValues : Bool) #

When true, then a comma is always inserted after values, otherwise commas are omitted.


[View source]
def commaAfterValues? : Bool #

When true, then a comma is always inserted after values, otherwise commas are omitted.


[View source]
def explicitRootObject? : Bool #

When true, and the toplevel value is an RSObject, then braces will be inserted around it (similar to JSON). Otherwise these are omitted, as permitted by the specs.


[View source]
def extraNewlineBetweenToplevelKeys=(extraNewlineBetweenToplevelKeys : Bool) #

When true, then an extra newline is added after every topevel key/value pair (i.e., an extra blank line between each pair). Otherwise only a single newline is emitted after each pair.


[View source]
def extraNewlineBetweenToplevelKeys? : Bool #

When true, then an extra newline is added after every topevel key/value pair (i.e., an extra blank line between each pair). Otherwise only a single newline is emitted after each pair.


[View source]
def finishArray : self #

Finishes writing an array.


[View source]
def finishObject : self #

Finishes writing an object.


[View source]
def indentSize : UInt32 #

The size of the indent (ASCII spaces).


[View source]
def indentSize=(indentSize : UInt32) #

The size of the indent (ASCII spaces).


[View source]
def startArray : self #

Begins writing an array. After writing all of your values, you must finish the array by calling #finishArray.


[View source]
def startObject : self #

Begins writing an object. After writing all of your key/value pairs, you must finish the object by calling #finishObject.


[View source]
def startToplevel(toplevelIsArray : Bool) : self #

Starts the toplevel value of the document. This can only be called once, and must be the first element written.


[View source]
def state : State #

Returns the current state of the Builder instance.


[View source]
def stream : IO #

Returns the underlying IO.


[View source]
def writeArray(&) : self #

Calls #startArray and then yields to the block. After the block finishes, this calls #finishArray.

str = RemiLib::RSConf::Builder.build do |builder|
  builder.writeArray do
    builder.writeValue(1).writeValue(2).writeValue(3)
  end
end

puts str # RSConf data with the values 1, 2, 3 as an array,

[View source]
def writeArray(values : Array(T)) : self forall T #

Calls #startArray and then writes all of the values in values by calling #writeValue. This then calls #finishArray before returning.


[View source]
def writeArray(values : Set(T)) : self forall T #

Calls #startArray and then writes all of the values in values by calling #writeValue. This then calls #finishArray before returning.


[View source]
def writeArray(*values) : self #

Calls #startArray and then writes all of the values in values by calling #writeValue. This then calls #finishArray before returning.


[View source]
def writeBlankLine : self #

Writes a newline.


[View source]
def writeBlockComment(str : String, *, depth : Int = 2, maxWidth : Int = 80) : self #

Wraps str so that it will fit into maxWidth columns, including depth number of semicolons before each line. This then writes the wrapped comment. This will automatically insert one blank comment line before and after str (the lines still have their semicolons, but no lines from str). This essentially lets you write "block" comments.

The depth parameter indicates how many semicolons are written, and must be at least 1.

Note that RSConf prefers Common Lisp-style commenting. Check the official specifications for more information.


[View source]
def writeComment(str : String, depth : Int = 2) : self #

Writes a comment. The depth parameter indicates how many semicolons are written, and must be at least 1.

Note that RSConf prefers Common Lisp-style commenting. Check the official specifications for more information.


[View source]
def writeKey(key : String) : self #

Writes a key name. This can only be called while writing an object (see #startObject). After calling this, you must call #writeValue to finish the key/value pair.


[View source]
def writeNil : self #

Writes a null value. This must be called within an array or after writing a key in an object.


[View source]
def writeObject(&) : self #

Calls #startObject and then yields to the block. After the block finishes, this calls #finishObject.


[View source]
def writeObject(pairs : Hash(String, T)) : self forall T #

Calls #startObject and then writes all of the key/value pairs in pairs by calling #writePair. This then calls #finishObject before returning.


[View source]
def writeObject(*pairs : Tuple(String, T)) : self forall T #

Calls #startObject and then writes all of the key/value pairs in pairs by calling #writePair. This then calls #finishObject before returning.


[View source]
def writePair(key : String, val) : self #

Writes a key/value pair. This can only be called while writing an object (see #startObject).

str = RemiLib::RSConf::Builder.build do |builder|
  builder.writePair("key", "the value")
end

puts str

[View source]
def writePair(key : String, &) : self #

Writes the given key then yields to the block. The block must write the value for this pair somewhere inside of it.

str = RemiLib::RSConf::Builder.build do |builder|
  builder.writePair("key") do
    builder.writeValue(Random.rand(69))
  end
end

puts str

[View source]
def writeValue(str : String) : self #

Writes a string value. This must be called within an array or after writing a key in an object.


[View source]
def writeValue(num : Float32 | Float64) : self #

Writes a float value. This must be called within an array or after writing a key in an object.


[View source]
def writeValue(num : Int) : self #

Writes an integer value. This must be called within an array or after writing a key in an object. The integer must fit into an RSInteger.


[View source]
def writeValue(val : Bool) : self #

Writes a string value. This must be called within an array or after writing a key in an object.


[View source]
def writeValue(val : Nil) : self #

Writes a null value. This must be called within an array or after writing a key in an object.


[View source]
def writeValue(val : RSScalar) : self #

Writes the value of an RSScalar instance. This must be called within an array or after writing a key in an object.


[View source]
def writeValue(val) : self #

Writes a string value. This must be called within an array or after writing a key in an object.


[View source]
def writeValue(&) : self #

Yields an IO::Memory instance to the block. Once the block returns, this writes the string from the IO::Memory using #writeValue(String). This must be called within an array or after writing a key in an object.


[View source]
def writeValues(values : Array(T)) : self forall T #

Writes values by calling #writeValue on each element.


[View source]
def writeValues(values : Set(T)) : self forall T #

Writes values by calling #writeValue on each element.


[View source]
def writeValues(*values) : self #

Writes values by calling #writeValue on each parameter.


[View source]
def writeWrappedComment(str : String, *, depth : Int = 2, maxWidth : Int = 80, extraBefore : Int = 0, extraAfter : Int = 0) : self #

Wraps str so that it will fit into maxWidth columns, including depth number of semicolons before each line. This then writes the wrapped comment.

The depth parameter indicates how many semicolons are written, and must be at least 1.

The extraBefore and extraAfter parameters indicate how many extra blank comment lines are written before and after the str comment, respectively. These lines still have their semicolons, but no lines from str. This essentially lets you write "block" comments.

Note that RSConf prefers Common Lisp-style commenting. Check the official specifications for more information.


[View source]