Class: Codeball::Entry

Inherits:
Object
  • Object
show all
Defined in:
lib/codeball/entry.rb

Overview

A single file within a codeball.

Entry is a state machine with write-once setters for header, body, and footer. It enforces the Header -> Body -> Footer sequence by rejecting duplicate assignments and detecting mismatched footers.

Two construction paths, same invariants:

1. Token-by-token via Stream (parsing)
2. All-at-once via Entry.from_file (packing)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeEntry

Returns a new instance of Entry.



34
35
36
37
38
39
40
# File 'lib/codeball/entry.rb', line 34

def initialize
  @header = nil
  @body = nil
  @footer = nil
  @error = nil
  @magic_client = self.class.magic_client
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body.



16
17
18
# File 'lib/codeball/entry.rb', line 16

def body
  @body
end

#errorObject (readonly)

Returns the value of attribute error.



16
17
18
# File 'lib/codeball/entry.rb', line 16

def error
  @error
end

Returns the value of attribute footer.



16
17
18
# File 'lib/codeball/entry.rb', line 16

def footer
  @footer
end

#headerObject

Returns the value of attribute header.



16
17
18
# File 'lib/codeball/entry.rb', line 16

def header
  @header
end

Class Method Details

.from_file(path) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/codeball/entry.rb', line 18

def self.from_file(path)
  pathname = Pathname.new(path)
  return nil unless pathname.exist? && pathname.readable?

  entry = new
  name = pathname.to_s
  entry.header = Header.new(name)
  entry.body = Body.new(pathname.read)
  entry.footer = Footer.new(name)
  entry
end

.magic_clientObject



30
31
32
# File 'lib/codeball/entry.rb', line 30

def self.magic_client
  @magic_client ||= FileMagic.mime
end

Instance Method Details

#byte_sizeObject



76
# File 'lib/codeball/entry.rb', line 76

def byte_size = contents&.bytesize || 0

#contentsObject



73
# File 'lib/codeball/entry.rb', line 73

def contents = body&.to_s

#empty?Boolean

Returns:

  • (Boolean)


75
# File 'lib/codeball/entry.rb', line 75

def empty? = contents&.empty? || contents.nil?

#errors?Boolean

Returns:

  • (Boolean)


69
# File 'lib/codeball/entry.rb', line 69

def errors? = !error.nil?

#incomplete?Boolean

Returns:

  • (Boolean)


68
# File 'lib/codeball/entry.rb', line 68

def incomplete? = !valid? && !errors?

#line_countObject



78
79
80
81
82
# File 'lib/codeball/entry.rb', line 78

def line_count
  return 0 if contents.nil? || contents.empty?

  contents.count("\n") + (contents.end_with?("\n") ? 0 : 1)
end

#mime_typeObject



93
94
95
# File 'lib/codeball/entry.rb', line 93

def mime_type
  @mime_type ||= @magic_client.buffer(contents)
end

#pathObject



72
# File 'lib/codeball/entry.rb', line 72

def path = header&.to_s

#serializeObject



88
89
90
91
# File 'lib/codeball/entry.rb', line 88

def serialize
  border = Border::SEPARATOR
  "#{border}\nBEGIN #{path.inspect}\n#{border}\n#{contents}#{border}\nEND #{path.inspect}\n#{border}\n"
end

#text?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/codeball/entry.rb', line 84

def text?
  contents.nil? || contents.empty? || !mime_type.include?("charset=binary")
end

#truncated?Boolean

Returns:

  • (Boolean)


70
# File 'lib/codeball/entry.rb', line 70

def truncated? = !!(header && (body.nil? || footer.nil?) && !errors?)

#valid?Boolean

Returns:

  • (Boolean)


67
# File 'lib/codeball/entry.rb', line 67

def valid? = !!(header && body && footer && !errors? && footer_matches_header?)