fmt 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +170 -87
  3. data/lib/fmt/boot.rb +50 -0
  4. data/lib/fmt/lru_cache.rb +181 -0
  5. data/lib/fmt/mixins/matchable.rb +26 -0
  6. data/lib/fmt/models/arguments.rb +194 -0
  7. data/lib/fmt/models/embed.rb +48 -0
  8. data/lib/fmt/models/macro.rb +58 -0
  9. data/lib/fmt/models/model.rb +66 -0
  10. data/lib/fmt/models/pipeline.rb +47 -0
  11. data/lib/fmt/models/template.rb +55 -0
  12. data/lib/fmt/node.rb +128 -0
  13. data/lib/fmt/parsers/arguments_parser.rb +43 -0
  14. data/lib/fmt/parsers/embed_parser.rb +54 -0
  15. data/lib/fmt/parsers/macro_parser.rb +113 -0
  16. data/lib/fmt/parsers/parser.rb +56 -0
  17. data/lib/fmt/parsers/pipeline_parser.rb +41 -0
  18. data/lib/fmt/parsers/template_parser.rb +125 -0
  19. data/lib/fmt/refinements/kernel_refinement.rb +38 -0
  20. data/lib/fmt/registries/native_registry.rb +66 -0
  21. data/lib/fmt/registries/rainbow_registry.rb +36 -0
  22. data/lib/fmt/registries/registry.rb +127 -0
  23. data/lib/fmt/renderer.rb +132 -0
  24. data/lib/fmt/sigils.rb +23 -0
  25. data/lib/fmt/token.rb +126 -0
  26. data/lib/fmt/tokenizer.rb +96 -0
  27. data/lib/fmt/version.rb +3 -1
  28. data/lib/fmt.rb +51 -11
  29. data/sig/generated/fmt/boot.rbs +2 -0
  30. data/sig/generated/fmt/lru_cache.rbs +122 -0
  31. data/sig/generated/fmt/mixins/matchable.rbs +18 -0
  32. data/sig/generated/fmt/models/arguments.rbs +115 -0
  33. data/sig/generated/fmt/models/embed.rbs +34 -0
  34. data/sig/generated/fmt/models/macro.rbs +37 -0
  35. data/sig/generated/fmt/models/model.rbs +45 -0
  36. data/sig/generated/fmt/models/pipeline.rbs +31 -0
  37. data/sig/generated/fmt/models/template.rbs +33 -0
  38. data/sig/generated/fmt/node.rbs +64 -0
  39. data/sig/generated/fmt/parsers/arguments_parser.rbs +25 -0
  40. data/sig/generated/fmt/parsers/embed_parser.rbs +36 -0
  41. data/sig/generated/fmt/parsers/macro_parser.rbs +60 -0
  42. data/sig/generated/fmt/parsers/parser.rbs +44 -0
  43. data/sig/generated/fmt/parsers/pipeline_parser.rbs +25 -0
  44. data/sig/generated/fmt/parsers/template_parser.rbs +50 -0
  45. data/sig/generated/fmt/refinements/kernel_refinement.rbs +23 -0
  46. data/sig/generated/fmt/registries/native_registry.rbs +19 -0
  47. data/sig/generated/fmt/registries/rainbow_registry.rbs +11 -0
  48. data/sig/generated/fmt/registries/registry.rbs +69 -0
  49. data/sig/generated/fmt/renderer.rbs +70 -0
  50. data/sig/generated/fmt/sigils.rbs +30 -0
  51. data/sig/generated/fmt/token.rbs +77 -0
  52. data/sig/generated/fmt/tokenizer.rbs +51 -0
  53. data/sig/generated/fmt/version.rbs +5 -0
  54. data/sig/generated/fmt.rbs +41 -0
  55. metadata +126 -16
  56. data/lib/fmt/embed.rb +0 -19
  57. data/lib/fmt/filter.rb +0 -32
  58. data/lib/fmt/filters.rb +0 -76
  59. data/lib/fmt/formatter.rb +0 -50
  60. data/lib/fmt/scanners/base_scanner.rb +0 -41
  61. data/lib/fmt/scanners/embed_scanner.rb +0 -56
  62. data/lib/fmt/scanners/filter_scanner.rb +0 -31
  63. data/lib/fmt/scanners/key_scanner.rb +0 -15
  64. data/lib/fmt/scanners.rb +0 -3
  65. data/lib/fmt/transformer.rb +0 -63
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module Fmt
6
+ # Renders templates to a formatted string
7
+ class Renderer
8
+ PIPELINE_START = Regexp.new("(?=%s)" % [Sigils::FORMAT_PREFIX]).freeze # : Regexp -- detects start of first pipeline
9
+
10
+ # Constructor
11
+ # @rbs template: Template
12
+ def initialize(template)
13
+ @template = template
14
+ end
15
+
16
+ attr_reader :template # : Template
17
+
18
+ # Renders the template to a string
19
+ # @note Positional and Keyword arguments are mutually exclusive
20
+ # @rbs args: Array[Object] -- positional arguments (user provided)
21
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
22
+ # @rbs return: String -- rendered template
23
+ def render(*args, **kwargs)
24
+ raise Error, "positional and keyword arguments are mutually exclusive" if args.any? && kwargs.any?
25
+
26
+ context = template.source
27
+
28
+ render_embeds(context, *args, **kwargs) do |embed, result|
29
+ kwargs[embed.key] = result
30
+ end
31
+
32
+ render_pipelines(context, *args, **kwargs)
33
+ end
34
+
35
+ private
36
+
37
+ # Escapes a string for use in a regular expression
38
+ # @rbs value: String -- string to escape
39
+ # @rbs return: String -- escaped string
40
+ def esc(value) = Regexp.escape(value.to_s)
41
+
42
+ # Renders all template embeds
43
+ # @rbs context: String -- starting context
44
+ # @rbs args: Array[Object] -- positional arguments (user provided)
45
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
46
+ # @rbs &block: Proc -- block to execute after rendering embeds (signature: Proc(String, *args, **kwargs))
47
+ def render_embeds(context, *args, **kwargs)
48
+ template.embeds.each do |embed|
49
+ yield embed, Renderer.new(embed.template).render(*args, **kwargs)
50
+ end
51
+ end
52
+
53
+ # Renders all template pipelines
54
+ # @rbs context: String -- starting context
55
+ # @rbs args: Array[Object] -- positional arguments (user provided)
56
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
57
+ # @rbs return: String
58
+ def render_pipelines(context, *args, **kwargs)
59
+ template.pipelines.each_with_index do |pipeline, index|
60
+ result = render_pipeline(pipeline, *args[index..], **kwargs)
61
+ context = context.sub(pipeline.urtext, result)
62
+ end
63
+
64
+ context
65
+ end
66
+
67
+ # Renders a single pipeline
68
+ # @rbs pipeline: Pipeline -- pipeline to render
69
+ # @rbs args: Array[Object] -- positional arguments (user provided)
70
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
71
+ # @rbs return: String
72
+ def render_pipeline(pipeline, *args, **kwargs)
73
+ result = ""
74
+
75
+ pipeline.macros.each do |macro|
76
+ result = case macro
77
+ in name: Sigils::FORMAT_METHOD
78
+ case [args, kwargs]
79
+ in [], {} then invoke_formatter(macro)
80
+ in [], {**} => kwargs then invoke_formatter(macro, **kwargs)
81
+ in [*], {} then invoke_formatter(macro, *args)
82
+ in [*], {**} => kwargs then invoke_formatter(macro, *args, **kwargs)
83
+ end
84
+ else invoke_macro(result, macro)
85
+ end
86
+ end
87
+
88
+ result
89
+ end
90
+
91
+ # Invokes native Ruby string formatting
92
+ # @rbs macro: Macro -- macro to use (source, arguments, etc.)
93
+ # @rbs args: Array[Object] -- positional arguments (user provided)
94
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
95
+ # @rbs return: String
96
+ def invoke_formatter(macro, *args, **kwargs)
97
+ callable = Fmt.registry[[Kernel, macro.name]]
98
+ context = macro.arguments.args[0]
99
+ context.instance_exec(*args, **kwargs, &callable)
100
+ rescue => error
101
+ raise_format_error(macro, *args, cause: error, **kwargs)
102
+ end
103
+
104
+ # Invokes a macro
105
+ # @rbs context: Object -- self in callable (Proc)
106
+ # @rbs macro: Macro -- macro to use (source, arguments, etc.)
107
+ # @rbs return: Object -- result
108
+ def invoke_macro(context, macro)
109
+ callable = Fmt.registry[[context.class, macro.name]] || Fmt.registry[[Object, macro.name]]
110
+ raise Error, "[#{context.class.name} | Object, #{macro.name}] is not a registered formatter!" unless callable
111
+
112
+ args = macro.arguments.args
113
+ kwargs = macro.arguments.kwargs
114
+
115
+ context.instance_exec(*args, **kwargs, &callable)
116
+ rescue => error
117
+ args ||= []
118
+ kwargs ||= {}
119
+ raise_format_error(macro, *args, cause: error, **kwargs)
120
+ end
121
+
122
+ # Raises an invocation error if/when Proc invocations fail
123
+ # @rbs macro: Macro -- macro that failed
124
+ # @rbs args: Array[Object] -- positional arguments (user provided)
125
+ # @rbs cause: Exception -- exception that caused the error
126
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
127
+ # @rbs return: void
128
+ def raise_format_error(macro, *args, cause:, **kwargs)
129
+ raise FormatError, "Error in macro! `#{macro.urtext}` args=#{args.inspect} kwargs=#{kwargs.inspect} cause=#{cause.inspect}"
130
+ end
131
+ end
132
+ end
data/lib/fmt/sigils.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module Fmt
6
+ # Common Fmt sigils (used in String templates)
7
+ class Sigils
8
+ # Native Ruby format specifiers
9
+ # @see https://docs.ruby-lang.org/en/master/format_specifications_rdoc.html
10
+ FORMAT_PREFIX = "%" # : String -- start of a format string (i.e. a template)
11
+ FORMAT_SPECIFIERS = %w[A E G X a b c d e f g i o p s u x].freeze # : Array[String] -- format specifiers
12
+ FORMAT_FLAGS = [" ", "#", "+", "-", "0", ":", "::", "^", "_"].freeze # : Array[String] -- format flags
13
+ FORMAT_METHOD = :sprintf # : Symbol -- format method name
14
+
15
+ KEY_PREFIXES = ["<", "{"].freeze # : Array[String] -- keyed template prefix
16
+ KEY_SUFFIXES = [">", "}"].freeze # : Array[String] -- keyed template suffix
17
+ ARGS_PREFIX = "(" # : String -- macro arguments prefix
18
+ ARGS_SUFFIX = ")" # : String -- macro arguments suffix
19
+ PIPE_OPERATOR = "|>" # : String -- macro delimiter
20
+ EMBED_PREFIX = "{{" # : String -- embed prefix
21
+ EMBED_SUFFIX = "}}" # : String -- embed prefix
22
+ end
23
+ end
data/lib/fmt/token.rb ADDED
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module Fmt
6
+ # Convenience wrapper for Ripper tokens
7
+ #
8
+ # @see https://rubyapi.org/3.4/o/ripper
9
+ # @see doc/RIPPER.md (cheetsheet)
10
+ #
11
+ # @example Ripper Token
12
+ # [[lineno, column], type, token, state]
13
+ # [[Integer, Integer], Symbol, String, Object]
14
+ #
15
+ class Token
16
+ include Matchable
17
+
18
+ # Constructor
19
+ # @rbs ripper_token: Array[[Integer, Integer], Symbol, String, Object] -- Ripper token
20
+ def initialize(ripper_token)
21
+ (lineno, column), type, token, state = ripper_token
22
+ @ripper_token = ripper_token
23
+ @lineno = lineno
24
+ @column = column
25
+ @type = type.to_s.delete_prefix("on_").to_sym # strip Ripper's "on_" prefix for parser semantics
26
+ @token = token
27
+ @state = state
28
+ freeze
29
+ end
30
+
31
+ attr_reader :ripper_token # : Array[[Integer, Integer], Symbol, String, Object]
32
+ attr_reader :lineno # : Integer
33
+ attr_reader :column # : Integer
34
+ attr_reader :type # : Symbol
35
+ attr_reader :token # : String
36
+ attr_reader :state # : Object
37
+
38
+ # @note The entire data structure is considered a "token"
39
+ # Alias the embedded "token" as "value" to reduce confusion
40
+ alias_method :value, :token
41
+
42
+ # Returns a Hash representation of the token
43
+ # @rbs return: Hash[Symbol, Object]
44
+ def to_h
45
+ {
46
+ lineno: lineno,
47
+ column: column,
48
+ type: type,
49
+ token: token,
50
+ value: token,
51
+ state: state
52
+ }
53
+ end
54
+
55
+ # --------------------------------------------------------------------------
56
+ # @!group Pattern Matching Support
57
+ # --------------------------------------------------------------------------
58
+ alias_method :deconstruct, :ripper_token
59
+
60
+ # Returns a Hash representation of the token limited to the given keys
61
+ # @rbs keys: Array[Symbol] -- keys to include
62
+ # @rbs return: Hash[Symbol, Object]
63
+ def deconstruct_keys(keys = [])
64
+ to_h.select { _1 in ^keys }
65
+ end
66
+
67
+ # --------------------------------------------------------------------------
68
+ # @!group Helpers
69
+ # --------------------------------------------------------------------------
70
+
71
+ # Indicates if the token is a left paren (i.e. start of arguments)
72
+ # @rbs return: bool
73
+ def arguments_start?
74
+ type == :lparen
75
+ end
76
+
77
+ # Indicates if the token is a right paren (i.e. end of arguments)
78
+ # @rbs return: bool
79
+ def arguments_finish?
80
+ type == :rparen
81
+ end
82
+
83
+ # Indicates if the token starts a key (string formatting named parameter)
84
+ # @rbs return: bool
85
+ def key_start?
86
+ type == :lbrace || (type == :op && value == "<")
87
+ end
88
+
89
+ # Indicates if the token finishes a key (string formatting named parameter)
90
+ # @rbs return: bool
91
+ def key_finish?
92
+ type == :rbrace || (type == :op && value == ">")
93
+ end
94
+
95
+ # Indicates if the token is an identifier (e.g. method name, format specifier, variable name, etc.)
96
+ # @rbs return: bool
97
+ def identifier?
98
+ type == :ident
99
+ end
100
+
101
+ # Indicates if the token is a method name (i.e. method name or operator)
102
+ # @rbs return: bool
103
+ def method_name?
104
+ identifier? || operator?
105
+ end
106
+
107
+ # Indicates if the token is an operator
108
+ # @rbs return: bool
109
+ def operator?
110
+ type == :op
111
+ end
112
+
113
+ # Indicates if the token is a whitespace
114
+ # @rbs return: bool
115
+ def whitespace?
116
+ type == :on_sp
117
+ end
118
+
119
+ # Indicates if the token is a native String format specifier
120
+ # @see Sigils::FORMAT_SPECIFIERS
121
+ # @rbs return: bool
122
+ def specifier?
123
+ identifier? && value in Sigils::FORMAT_SPECIFIERS
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rbs_inline: enabled
4
+
5
+ module Fmt
6
+ # Ruby source code token extractor
7
+ #
8
+ # Uses Ripper from Ruby's standard library
9
+ # @see https://rubyapi.org/3.4/o/ripper
10
+ # @see doc/RIPPER.md (cheetsheet)
11
+ #
12
+ # @example Ripper token
13
+ # [[lineno, column], type, token, state]
14
+ # [[Integer, Integer], Symbol, String, Object]
15
+ #
16
+ class Tokenizer
17
+ # Constructor
18
+ # @rbs urtext: String -- original source code
19
+ def initialize(urtext)
20
+ @urtext = urtext.to_s
21
+ @tokens = []
22
+ end
23
+
24
+ attr_reader :urtext # : String -- original source code
25
+ attr_reader :tokens # : Array[Object] -- result of tokenization
26
+
27
+ # Tokenizes the urtext (original source code)
28
+ # @rbs return: Array[Token] -- wrapped ripper tokens
29
+ def tokenize
30
+ Ripper.lex(urtext).each do |token|
31
+ tokens << Token.new(token)
32
+ end
33
+ tokens
34
+ end
35
+
36
+ # Returns identifier tokens (typically method names)
37
+ # @rbs start: Integer -- start index
38
+ # @rbs return: Array[Token]
39
+ def identifier_tokens(start: 0)
40
+ tokens[start..].each_with_object([]) do |token, memo|
41
+ break memo if token.arguments_start?
42
+ memo << token if token.identifier?
43
+ end
44
+ end
45
+
46
+ # Returns method tokens (identifiers and operators)
47
+ # @rbs start: Integer -- start index
48
+ # @rbs return: Array[Token]
49
+ def method_name_tokens(start: 0)
50
+ identifier_tokens(start: start) + operator_tokens(start: start)
51
+ end
52
+
53
+ # Returns key (named parameter) tokens
54
+ # @rbs start: Integer -- start index
55
+ # @rbs return: Array[Token]?
56
+ def key_tokens(start: 0)
57
+ start = tokens[start..].find(&:key_start?)
58
+ identifier = tokens[tokens.index(start)..].find(&:identifier?) if start
59
+ finish = tokens[tokens.index(identifier)..].find(&:key_finish?) if identifier
60
+ list = [start, identifier, finish].compact
61
+
62
+ return [] unless list.size == 3
63
+ return [] unless urtext.include?(list.map(&:value).join)
64
+
65
+ list
66
+ end
67
+
68
+ # Returns operator tokens
69
+ # @rbs start: Integer -- start index
70
+ # @rbs return: Array[Token]
71
+ def operator_tokens(start: 0)
72
+ tokens[start..].each_with_object([]) do |token, memo|
73
+ break memo if token.arguments_start?
74
+ memo << token if token.operator?
75
+ end
76
+ end
77
+
78
+ # Returns the argument tokens
79
+ # @rbs start: Integer -- start index
80
+ # @rbs return: Array[Token]
81
+ def argument_tokens(start: 0)
82
+ starters = 0
83
+ finishers = 0
84
+
85
+ tokens[start..].each_with_object([]) do |token, memo|
86
+ break memo if starters.positive? && finishers == starters
87
+
88
+ starters += 1 if token.arguments_start?
89
+ next if starters.zero?
90
+
91
+ finishers += 1 if token.arguments_finish?
92
+ memo << token
93
+ end
94
+ end
95
+ end
96
+ end
data/lib/fmt/version.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rbs_inline: enabled
4
+
3
5
  module Fmt
4
- VERSION = "0.1.2"
6
+ VERSION = "0.3.0"
5
7
  end
data/lib/fmt.rb CHANGED
@@ -1,28 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "fmt/version"
4
- require_relative "fmt/formatter"
3
+ # rbs_inline: enabled
4
+ #
5
+ require_relative "fmt/boot"
5
6
 
7
+ # Extends native Ruby String format specifications
8
+ # @see https://ruby-doc.org/3.3.4/format_specifications_rdoc.html
6
9
  module Fmt
10
+ LOCK = Monitor.new # : Monitor
11
+ private_constant :LOCK
12
+
13
+ # Standard error class for Fmt
7
14
  class Error < StandardError; end
8
15
 
16
+ # Error for formatting failures
17
+ class FormatError < Error; end
18
+
9
19
  class << self
10
- def formatter
11
- Formatter.instance
20
+ # Global registry for storing and retrieving String formatters i.e. Procs
21
+ def registry
22
+ @registry ||= LOCK.synchronize do
23
+ NativeRegistry.new.merge! RainbowRegistry.new
24
+ end
12
25
  end
13
26
 
14
- def filters
15
- formatter.filters
27
+ # Adds a keypair to the registry
28
+ # @rbs key: Array[Class | Module, Symbol] -- key to use
29
+ # @rbs overwrite: bool -- overwrite the existing keypair (default: false)
30
+ # @rbs block: Proc -- Proc to add (optional, if proc is provided)
31
+ # @rbs return: Proc
32
+ def register(...)
33
+ registry.add(...)
16
34
  end
17
35
 
18
- def add_filter(...)
19
- formatter.filters.add(...)
36
+ # Deletes a keypair from the registry
37
+ # @rbs key: Array[Class | Module, Symbol] -- key to delete
38
+ # @rbs return: Proc?
39
+ def unregister(...)
40
+ registry.delete(...)
20
41
  end
21
42
 
22
- alias_method :add, :add_filter
43
+ # Executes a block with registry overrides
44
+ #
45
+ # @note Overrides will temporarily be added to the registry
46
+ # and will overwrite existing entries for the duration of the block
47
+ # Non overriden entries remain unchanged
48
+ #
49
+ # @rbs overrides: Hash[Array[Class | Module, Symbol], Proc] -- overrides to apply
50
+ # @rbs block: Proc -- block to execute with overrides
51
+ # @rbs return: void
52
+ def with_overrides(...)
53
+ registry.with_overrides(...)
54
+ end
23
55
  end
24
56
  end
25
57
 
26
- def Fmt(...)
27
- Fmt.formatter.format(...)
58
+ # Top level helper for formatting and rendering a source string
59
+ # @rbs source: String -- string to format
60
+ # @rbs args: Array[Object] -- positional arguments (user provided)
61
+ # @rbs kwargs: Hash[Symbol, Object] -- keyword arguments (user provided)
62
+ # @rbs return: String -- rendered template
63
+ def Fmt(source, *args, **kwargs)
64
+ ast = Fmt::TemplateParser.new(source).parse
65
+ template = Fmt::Template.new(ast)
66
+ renderer = Fmt::Renderer.new(template)
67
+ renderer.render(*args, **kwargs)
28
68
  end
@@ -0,0 +1,2 @@
1
+ # Generated from lib/fmt/boot.rb with RBS::Inline
2
+
@@ -0,0 +1,122 @@
1
+ # Generated from lib/fmt/lru_cache.rb with RBS::Inline
2
+
3
+ module Fmt
4
+ # A threadsafe fixed-size LRU in-memory cache
5
+ # Grows to capacity then evicts the least used entries
6
+ #
7
+ # @example
8
+ # cache = Fmt::Cache.new
9
+ #
10
+ # cache.put :key, "value"
11
+ # cache.get :key
12
+ # cache.delete :key
13
+ # cache.fetch :key, "default"
14
+ # cache.fetch(:key) { "default" }
15
+ #
16
+ # @example Capacity
17
+ # Fmt::Cache.capacity = 10_000
18
+ class LRUCache
19
+ include MonitorMixin
20
+
21
+ DEFAULT_CAPACITY: ::Integer
22
+
23
+ # Constructor
24
+ # @rbs capacity: Integer -- max capacity (negative values are uncapped, default: 5_000)
25
+ # @rbs return: Fmt::Cache
26
+ def initialize: (?capacity: Integer) -> Fmt::Cache
27
+
28
+ # The cache max capacity (number of entries)
29
+ # @rbs return: Integer
30
+ def capacity: () -> Integer
31
+
32
+ # Set the max capacity (number of entries)
33
+ # @rbs capacity: Integer -- new max capacity
34
+ # @rbs return: Integer -- new max capacity
35
+ def capacity=: (Integer capacity) -> Integer
36
+
37
+ # Indicates if the cache is capped
38
+ # @rbs return: bool
39
+ def capped?: () -> bool
40
+
41
+ # Clears the cache
42
+ # @rbs return: void
43
+ def clear: () -> void
44
+
45
+ # Deletes the entry for the specified key
46
+ # @rbs key: Object -- key to delete
47
+ # @rbs return: Object? -- the deleted value
48
+ def delete: (Object key) -> Object?
49
+
50
+ # Fetches the value for the specified key
51
+ # Writes the default value if the key is not found
52
+ # @rbs key: Object -- key to fetch
53
+ # @rbs default: Object -- default value to write
54
+ # @rbs block: Proc -- block to call to get the default value
55
+ # @rbs return: Object -- value
56
+ def fetch: (Object key, ?Object default) ?{ (?) -> untyped } -> Object
57
+
58
+ # Fetches a value from the cache without synchronization (not thread safe)
59
+ # @rbs key: Object -- key to fetch
60
+ # @rbs default: Object -- default value to write
61
+ # @rbs block: Proc -- block to call to get the default value
62
+ # @rbs return: Object -- value
63
+ def fetch_unsafe: (Object key, ?Object default) ?{ (?) -> untyped } -> Object
64
+
65
+ # Indicates if the cache is full
66
+ # @rbs return: bool
67
+ def full?: () -> bool
68
+
69
+ # Retrieves the value for the specified key
70
+ # @rbs key: Object -- key to retrieve
71
+ def get: (Object key) -> untyped
72
+
73
+ # Cache keys
74
+ # @rbs return: Array[Object]
75
+ def keys: () -> Array[Object]
76
+
77
+ # Indicates if the cache contains the specified key
78
+ # @rbs key: Object -- key to check
79
+ # @rbs return: bool
80
+ def key?: (Object key) -> bool
81
+
82
+ # Stores the value for the specified key
83
+ # @rbs key: Object -- key to store
84
+ # @rbs value: Object -- value to store
85
+ # @rbs return: Object -- value
86
+ def put: (Object key, Object value) -> Object
87
+
88
+ # Resets the cache capacity to the default
89
+ # @rbs return: Integer -- capacity
90
+ def reset_capacity: () -> Integer
91
+
92
+ # The current size of the cache (number of entries)
93
+ # @rbs return: Integer
94
+ def size: () -> Integer
95
+
96
+ # Returns a Hash with only the given keys
97
+ # @rbs keys: Array[Object] -- keys to include
98
+ # @rbs return: Hash[Object, Object]
99
+ def slice: (*untyped keys) -> Hash[Object, Object]
100
+
101
+ # Hash representation of the cache
102
+ # @rbs return: Hash[Object, Proc]
103
+ def to_h: () -> Hash[Object, Proc]
104
+
105
+ # Cache values
106
+ # @rbs return: Array[Object]
107
+ def values: () -> Array[Object]
108
+
109
+ # Executes a block with a synchronized mutex
110
+ # @rbs block: Proc -- block to execute
111
+ def lock: () ?{ (?) -> untyped } -> untyped
112
+
113
+ private
114
+
115
+ attr_reader store: untyped
116
+
117
+ # Moves the key to the end keeping it fresh
118
+ # @rbs key: Object -- key to reposition
119
+ # @rbs return: Object -- value
120
+ def reposition: (Object key) -> Object
121
+ end
122
+ end
@@ -0,0 +1,18 @@
1
+ # Generated from lib/fmt/mixins/matchable.rb with RBS::Inline
2
+
3
+ module Fmt
4
+ module Matchable
5
+ # Hash representation of the Object (required for pattern matching)
6
+ # @rbs return: Hash[Symbol, Object]
7
+ def to_h: () -> Hash[Symbol, Object]
8
+
9
+ # Returns a Hash representation of the object limited to the given keys
10
+ # @rbs keys: Array[Symbol] -- keys to include
11
+ # @rbs return: Hash[Symbol, Object]
12
+ def deconstruct_keys: (?Array[Symbol] keys) -> Hash[Symbol, Object]
13
+
14
+ # Returns an Array representation of the object
15
+ # @rbs return: Array[Object]
16
+ def deconstruct: () -> Array[Object]
17
+ end
18
+ end