Class: Fusion::CLI::Options

Inherits:
Object
  • Object
show all
Defined in:
lib/fusion/cli/options.rb

Defined Under Namespace

Classes: UsageError

Constant Summary collapse

USAGE =
<<~TEXT
  usage: fusion [options] <file.fsn>
         fusion [options] -e '<source>'
         fusion --repl

  use cases (default: --repl with no arguments, otherwise --pipe):
    -p, --pipe      apply the program to stdin; with no input, the
                    program's own value is the result
    -s, --stream    apply the program to each line of an NDJSON stream
    -r, --repl      interactive expressions and `identifier = expression`

  options:
    -e, --execute '<source>'
                    inline program instead of a file
    -i, --input MODE
                    how the input marks an error value
    -o, --output MODE
                    how the output marks an error value
    -j, --jail DIR  confine @-references to DIR and its subtree
                    (default: the program's directory; the stdlib is
                    always reachable, stdin never contains @-references;
                    use '*' to disable confinement)
    -!              treat the input as an error value (unix input mode only)
    -b, --skip-blank-lines
                    drop blank input lines instead of echoing them (--stream only)

  modes: unix, bang, array, object
    unix    pipe only (default there): plain JSON; output: stdout/exit 0
            for values, stderr/exit 1 for error payloads
    bang    a leading "!" marks an error value; cheapest encoding, but not
            valid JSON — prefer it only between Fusion programs
    array   [0, value] marks a value, [1, payload] an error (default for --stream)
    object  {"value": _} marks a value, {"error": _} an error
TEXT
MODES =
%w[unix bang array object].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(use_case:, input_mode:, output_mode:, inline_source:, program_path:, error_input:, skip_blank_lines:, jail:) ⇒ Options

Returns a new instance of Options.



59
60
61
62
63
64
65
66
67
68
# File 'lib/fusion/cli/options.rb', line 59

def initialize(use_case:, input_mode:, output_mode:, inline_source:, program_path:, error_input:, skip_blank_lines:, jail:)
  @use_case = use_case
  @input_mode = input_mode
  @output_mode = output_mode
  @inline_source = inline_source
  @program_path = program_path
  @error_input = error_input
  @skip_blank_lines = skip_blank_lines
  @jail = jail
end

Instance Attribute Details

#inline_sourceObject (readonly)

Returns the value of attribute inline_source.



57
58
59
# File 'lib/fusion/cli/options.rb', line 57

def inline_source
  @inline_source
end

#input_modeObject (readonly)

Returns the value of attribute input_mode.



57
58
59
# File 'lib/fusion/cli/options.rb', line 57

def input_mode
  @input_mode
end

#jailObject (readonly)

Returns the value of attribute jail.



57
58
59
# File 'lib/fusion/cli/options.rb', line 57

def jail
  @jail
end

#output_modeObject (readonly)

Returns the value of attribute output_mode.



57
58
59
# File 'lib/fusion/cli/options.rb', line 57

def output_mode
  @output_mode
end

#program_pathObject (readonly)

Returns the value of attribute program_path.



57
58
59
# File 'lib/fusion/cli/options.rb', line 57

def program_path
  @program_path
end

#use_caseObject (readonly)

Returns the value of attribute use_case.



57
58
59
# File 'lib/fusion/cli/options.rb', line 57

def use_case
  @use_case
end

Class Method Details

.parse(argv) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/fusion/cli/options.rb', line 78

def self.parse(argv)
  pipe = false
  stream = false
  repl = false
  input_modes = []
  output_modes = []
  error_input = false
  skip_blank_lines = false
  inline_source = nil
  jail = nil

  parser = OptionParser.new do |option|
    option.on("-p", "--pipe") { pipe = true }
    option.on("-s", "--stream") { stream = true }
    option.on("-r", "--repl") { repl = true }
    option.on("-i", "--input MODE") { |mode| input_modes << check_mode!(mode, "--input") }
    option.on("-o", "--output MODE") { |mode| output_modes << check_mode!(mode, "--output") }
    option.on("-e", "--execute SOURCE") { |source| inline_source = source }
    option.on("-j", "--jail DIR") { |dir| jail = dir }
    option.on("-!") { error_input = true }
    option.on("-b", "--skip-blank-lines") { skip_blank_lines = true }
  end
  parser.require_exact = true # no abbreviations: "--s" is not a stand-in for "--stream"

  # Whatever survives option parsing is positional: the program path.
  positional = run_parser(parser, argv)

  use_case = resolve_use_case(pipe: pipe, stream: stream, repl: repl, no_arguments: argv.empty?)
  input_mode = resolve_mode(input_modes, "--input")
  output_mode = resolve_mode(output_modes, "--output")

  validate(use_case, input_mode, output_mode, error_input, skip_blank_lines, inline_source, jail, positional)
end

Instance Method Details

#error_input?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/fusion/cli/options.rb', line 70

def error_input?
  @error_input
end

#skip_blank_lines?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/fusion/cli/options.rb', line 74

def skip_blank_lines?
  @skip_blank_lines
end