summaryrefslogtreecommitdiff
path: root/lib/oxidized/model/model.rb
blob: c3d8760018f46d5a4e2e620f1c1901351c25dbbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
module Oxidized
  class Model
    include Oxidized::Config::Vars

    class << self
      def inherited klass
        klass.instance_variable_set '@cmd',   Hash.new { |h,k| h[k] = [] }
        klass.instance_variable_set '@cfg',   Hash.new { |h,k| h[k] = [] }
        klass.instance_variable_set '@procs', Hash.new { |h,k| h[k] = [] }
        klass.instance_variable_set '@expect', []
        klass.const_set :CFG, CFG
      end
      def comment _comment='# '
        return @comment if @comment
        @comment = block_given? ? yield : _comment
      end
      def prompt _prompt=nil
        @prompt or @prompt = _prompt
      end
      def cfg *methods, &block
        [methods].flatten.each do |method|
          @cfg[method.to_s] << block
        end
      end
      def cfgs
        @cfg
      end
      def cmd _cmd=nil, &block
        if _cmd.class == Symbol
          @cmd[_cmd] << block
        else
          @cmd[:cmd] << [_cmd, block]
        end
      end
      def cmds
        @cmd
      end
      def expect re, &block
        @expect << [re, block]
      end
      def expects
        @expect
      end

      # calls the block at the end of the model, prepending the output of the
      # block to the output string
      #
      # @author Saku Ytti <saku@ytti.fi>
      # @since 0.0.39
      # @yield expects block which should return [String]
      # @return [void]
      def pre &block
        @procs[:pre] << block
      end

      # calls the block at the end of the model, adding the output of the block
      # to the output string
      #
      # @author Saku Ytti <saku@ytti.fi>
      # @since 0.0.39
      # @yield expects block which should return [String]
      # @return [void]
      def post &block
        @procs[:post] << block
      end

      # @author Saku Ytti <saku@ytti.fi>
      # @since 0.0.39
      # @return [Hash] hash proc procs :pre+:post to be prepended/postfixed to output
      def procs
        @procs
      end
    end

    attr_accessor :input, :node

    def cmd string, &block
      out = @input.cmd string
      return false unless out
      out = Oxidized::String.new out
      self.class.cmds[:all].each do |all_block|
        out = instance_exec out, string, &all_block
      end
      if vars :remove_secret
        self.class.cmds[:secret].each do |all_block|
          out = instance_exec out, string, &all_block
        end
      end
      out = instance_exec out, &block if block
      out
    end

    def output
      @input.output
    end

    def send data
      @input.send data
    end

    def expect re, &block
      self.class.expect re, &block
    end

    def cfg
      self.class.cfgs
    end

    def prompt
      self.class.prompt
    end

    def expects data
      self.class.expects.each do |re, cb|
        if data.match re
          if cb.arity == 2
            data = instance_exec [data, re], &cb
          else
            data = instance_exec data, &cb
          end
        end
      end
      data
    end

    def get
      data, pre = '', ''
      procs = self.class.procs
      self.class.cmds[:cmd].each do |command, block|
        out = cmd command, &block
        return false unless out
        data << out.to_s
      end
      procs[:pre].each do |pre_proc|
        pre << instance_eval(&pre_proc).to_s
      end
      procs[:post].each do |post_proc|
        data << instance_eval(&post_proc).to_s
      end
      pre + data
    end

    def comment _comment
      data = ''
      _comment.each_line do |line|
        data << self.class.comment << line
      end
      data
    end

  end
end