cecil 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25bc3ea619e4c5ed622fb086dbe51eeef561cbbfb733defad97dff14fd4ac0d5
4
- data.tar.gz: 1b66b8d83ed649fc3be60789ce0909efd20707a939f8f8a3cd7b7abde5e5c6da
3
+ metadata.gz: b6d1ee8839362c15c74ec48e0ed9fef3a3f3f32a93fc56587a30e8018446e2fe
4
+ data.tar.gz: cc183f942739ef6db6a51cb934b62823cf19f0251f6fd5c423bde1042a03332d
5
5
  SHA512:
6
- metadata.gz: 6370b9ec275ab1ecc3bfd03487088c89dc31f5c66dc53dc37de99eeda30968bd4ff39c020d4839df318aa302be4ad1e9dcbb843b7f224e34b9352a37f2f6c8f9
7
- data.tar.gz: 2dcb0a27ffdeef5271df1e222b80dc37908d9226a13b19e8e9427e1f73b85933736b5358e758501982aead5f9341f294e6ac6a9bc5ad4cec1d738bc4d171c5d9
6
+ metadata.gz: 2776e0ca696392d5a61bd9dbb306105ae64eee0a5371b7e1919a6b3c0a30128a223d39460e81fa0f0a7941231942792ac4578741db0bb37c7d7d8bcc582eba40
7
+ data.tar.gz: 73c04db6ba020b0e3494e28aac514fdc4ad913161fd9efb80a67a1acd76220ec4d1785175d2bb1f505ffdb6081589dd450f8ecb81e2c429ba009db9e90705bb4
data/.yard/README.md CHANGED
@@ -139,7 +139,7 @@ class User extends Model {
139
139
 
140
140
  ### Emit source code to other locations
141
141
 
142
- When generating source code, things like functions, parameters, classes, etc, often need to be declared, imported, or otherwise setup or before being used.
142
+ When generating source code, things like functions, parameters, classes, etc, often need to be declared, imported, or otherwise setup before being used.
143
143
 
144
144
  `content_for` can be used to add content to a different location of your file.
145
145
 
@@ -360,7 +360,7 @@ See: {Cecil::BlockContext Methods available inside a Cecil block}
360
360
  # })()
361
361
  ```
362
362
  - {Cecil::BlockContext#content_for `#content_for`} emits source code to different locations
363
- - {Cecil::BlockContext#defer `#defer`} for waits to emit the given source until after data has been gathered
363
+ - {Cecil::BlockContext#defer `#defer`} waits to emit the given source until after data has been gathered
364
364
 
365
365
  ### Customizing behavior for the language of the source code you're generating
366
366
 
@@ -372,6 +372,7 @@ Many of Cecil's defaults can be customized by creating a subclass of {Cecil::Cod
372
372
  Currently, Cecil comes with:
373
373
  - {Cecil::Code `Cecil::Code`} for generic code
374
374
  - {Cecil::Lang::TypeScript `Cecil::Lang::TypeScript`} for JavaScript and TypeScript
375
+ - {Cecil::Lang::Rust `Cecil::Lang::Rust`} for Rust
375
376
 
376
377
 
377
378
  ### Auto-closing brackets
@@ -409,7 +410,7 @@ becomes
409
410
  ```javascript
410
411
  user = ([{
411
412
  id: 42
412
- )}]
413
+ }])
413
414
  ```
414
415
 
415
416
  Currently, the algorithm is simplistic, so open brackets that aren't at the end of the string will *not* get closed.
@@ -419,7 +420,7 @@ In this example, the `(` in `test(` needs to be closed manually:
419
420
  ```ruby
420
421
  `test("getter $fn", () => {`[fn: 'getUsername'] do
421
422
  `assert(false)`
422
- end << `)'
423
+ end << `)`
423
424
  ```
424
425
 
425
426
  ```javascript
@@ -432,12 +433,12 @@ test("getter getUsername", () => {
432
433
 
433
434
  Default placeholder rules:
434
435
  - start with `$`-- e.g. `$foo`
435
- - named with alpha-numeric and underscore -- e.g. `$foo_bar123`
436
- - names can optionally be surrounded by optional brackets -- e.g `${my_placeholder}`
436
+ - named can contain alpha-numeric and underscore characters-- e.g. `$foo_bar123`
437
+ - names can optionally be surrounded by brackets -- e.g `${my_placeholder}`, `$[my_placeholder]`, `$<my_placeholder>`, or `$(my_placeholder)`
437
438
 
438
439
  Surrounding with brackets can be useful to separate a placeholder from subsequent characters that would otherwise get parsed as a placeholder.
439
440
 
440
- E.g. `function ${fn}Sync()`-- without curly brackets, the placeholder would be parsed as `fnSync`.
441
+ E.g. `function ${fn}Sync()`-- without curly brackets `$fnSync` would be the placeholder.
441
442
 
442
443
  Customize placeholder syntax by subclassing {Cecil::Code `Cecil::Code`}
443
444
  and overriding {Cecil::Code placeholder-related methods}.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cecil (0.1.3)
4
+ cecil (0.1.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -139,7 +139,7 @@ class User extends Model {
139
139
 
140
140
  ### Emit source code to other locations
141
141
 
142
- When generating source code, things like functions, parameters, classes, etc, often need to be declared, imported, or otherwise setup or before being used.
142
+ When generating source code, things like functions, parameters, classes, etc, often need to be declared, imported, or otherwise setup before being used.
143
143
 
144
144
  `content_for` can be used to add content to a different location of your file.
145
145
 
@@ -360,7 +360,7 @@ See: [Methods available inside a Cecil block][{BlockContext}]
360
360
  # })()
361
361
  ```
362
362
  - [`#content_for`][{BlockContext#content_for}] emits source code to different locations
363
- - [`#defer`][{BlockContext#defer}] for waits to emit the given source until after data has been gathered
363
+ - [`#defer`][{BlockContext#defer}] waits to emit the given source until after data has been gathered
364
364
 
365
365
  ### Customizing behavior for the language of the source code you're generating
366
366
 
@@ -372,6 +372,7 @@ Many of Cecil's defaults can be customized by creating a subclass of [`Cecil::Co
372
372
  Currently, Cecil comes with:
373
373
  - [`Cecil::Code`][{Code}] for generic code
374
374
  - [`Cecil::Lang::TypeScript`][{Lang::TypeScript}] for JavaScript and TypeScript
375
+ - [`Cecil::Lang::Rust`][{Lang::Rust}] for Rust
375
376
 
376
377
 
377
378
  ### Auto-closing brackets
@@ -409,7 +410,7 @@ becomes
409
410
  ```javascript
410
411
  user = ([{
411
412
  id: 42
412
- )}]
413
+ }])
413
414
  ```
414
415
 
415
416
  Currently, the algorithm is simplistic, so open brackets that aren't at the end of the string will *not* get closed.
@@ -419,7 +420,7 @@ In this example, the `(` in `test(` needs to be closed manually:
419
420
  ```ruby
420
421
  `test("getter $fn", () => {`[fn: 'getUsername'] do
421
422
  `assert(false)`
422
- end << `)'
423
+ end << `)`
423
424
  ```
424
425
 
425
426
  ```javascript
@@ -432,12 +433,12 @@ test("getter getUsername", () => {
432
433
 
433
434
  Default placeholder rules:
434
435
  - start with `$`-- e.g. `$foo`
435
- - named with alpha-numeric and underscore -- e.g. `$foo_bar123`
436
- - names can optionally be surrounded by optional brackets -- e.g `${my_placeholder}`
436
+ - named can contain alpha-numeric and underscore characters-- e.g. `$foo_bar123`
437
+ - names can optionally be surrounded by brackets -- e.g `${my_placeholder}`, `$[my_placeholder]`, `$<my_placeholder>`, or `$(my_placeholder)`
437
438
 
438
439
  Surrounding with brackets can be useful to separate a placeholder from subsequent characters that would otherwise get parsed as a placeholder.
439
440
 
440
- E.g. `function ${fn}Sync()`-- without curly brackets, the placeholder would be parsed as `fnSync`.
441
+ E.g. `function ${fn}Sync()`-- without curly brackets `$fnSync` would be the placeholder.
441
442
 
442
443
  Customize placeholder syntax by subclassing [`Cecil::Code`][{Code}]
443
444
  and overriding [placeholder-related methods][{Code}].
@@ -0,0 +1,91 @@
1
+ require_relative "../../cecil"
2
+
3
+ module Cecil
4
+ module Lang
5
+ class Rust < Code
6
+ # Overrides to use 4 spaces for indentation
7
+ def indent_chars = " "
8
+
9
+ # Overrides to ignore ambiguous indentation
10
+ def handle_ambiguous_indentation = Cecil::Indentation::Ambiguity.ignore
11
+
12
+ module Helpers
13
+ # Short for "list"; Accepts one or a list of strings and returns them joined with `", "`
14
+ #
15
+ # @param items [Array[#to_s], #to_s] One or a list of objects that respond to `#to_s`
16
+ # @return [String] The stringified inputs concatenated with `", "`
17
+ def l(items) = Array(items).compact.join(", ")
18
+
19
+ # Escapes codepoint as unicode character literal
20
+ # See https://doc.rust-lang.org/reference/tokens.html#unicode-escapes
21
+ def unicode_escape_codepoint(char_int) = "\\u{#{char_int.to_s(16)}}"
22
+
23
+ # Escapes string as unicode character literals
24
+ def unicode_escape(str) = str.each_codepoint.map { unicode_escape_codepoint(_1) }.join
25
+
26
+ # According to https://doc.rust-lang.org/reference/tokens.html#ascii-escapes
27
+ CHAR_TO_CUSTOM_ESCAPE_LITERAL = {
28
+ "\n" => '\n',
29
+ "\r" => '\r',
30
+ "\t" => '\t',
31
+ "\0" => '\0',
32
+ "\\" => "\\\\", # \ => \\
33
+ '"' => '\\"' # " => \"
34
+ }.freeze
35
+
36
+ # Escapes a character (string with one character) for use in a Rust string literal.
37
+ #
38
+ # @example
39
+ # rchar("\n") # => \n
40
+ # rchar('"') # => \"
41
+ # rchar('😉') # => \u{1f609}
42
+ def rchar(char)
43
+ CHAR_TO_CUSTOM_ESCAPE_LITERAL[char] ||
44
+ case char
45
+ when /^[ -~]$/ then char
46
+ else unicode_escape(char)
47
+ end
48
+ end
49
+
50
+ # Short for "string content"; returns escaped version of the string that can be inserted into a
51
+ # string literal.
52
+ #
53
+ # Useful for inserting data into a string or for outputting a string but using quotes to make it clear to the
54
+ # reader what the intended output will be.
55
+ #
56
+ # @example Inserting into a string literal
57
+ # name = %q{Bob "the Machine" O'Brian}
58
+ # `let admin = "$name (Admin)";`[s name]
59
+ #
60
+ # # outputs:
61
+ # # let admin = "Bob \"the Machine\" O\'Brian (Admin)";
62
+ #
63
+ # @param val [#to_s] A string or any object that responds to `#to_s`
64
+ # @return [String] A JSON string without quotes
65
+ def s(val) = val.each_char.map { rchar(_1) }.join
66
+
67
+ # short for "rust value"; returns a Rust literal version of the input.
68
+ #
69
+ # Currently handles strings, integers, floats, and booleans.
70
+ #
71
+ # @example
72
+ # `let name = $name;`[rs "Bob \"the Machine\" O\'Brian (Admin)"]
73
+ # `let age = $age;`[rs 42]
74
+ # `let friendliness = $friendliness;`[rs 9.9]
75
+ # `let is_admin = $is_admin;`[rs true]
76
+ #
77
+ # # outputs:
78
+ # # let name = "Bob \"the Machine\" O\'Brian (Admin)";
79
+ # # let age = 42;
80
+ # # let friendliness = 9.9;
81
+ # # let is_admin = true;
82
+ def rs(val)
83
+ case val
84
+ in String then %("#{s val}")
85
+ in Integer | Float | true | false then val.to_s
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
data/lib/cecil/node.rb CHANGED
@@ -357,6 +357,15 @@ module Cecil
357
357
  def self.build(src:, builder:, **kwargs)
358
358
  placeholders = builder.syntax.scan_for_placeholders(src)
359
359
 
360
+ # HACK: to make sure we throw the exception at the time the developer adds the string/template
361
+ #
362
+ # This gets called later, too, so it's work being done twice.
363
+ #
364
+ # This should probably be refactored so that Nodes carry around a de-indented version, and then just have to add
365
+ # the indentation later when stringified
366
+ Indentation.reindent(src, 0, "THIS SHOULD NEVER BE USED",
367
+ handle_ambiguity: builder.syntax.handle_ambiguous_indentation)
368
+
360
369
  if placeholders.any?
361
370
  new(src:, placeholders:, **kwargs)
362
371
  else
@@ -375,7 +384,7 @@ module Cecil
375
384
  def with(*positional_values, **named_values, &)
376
385
  src =
377
386
  case [positional_values, named_values, @placeholders]
378
- in [], {}, []
387
+ in [], {}, [] # TODO: is this case possible? should it be?
379
388
  @src
380
389
  in [], _, _
381
390
  Text.interpolate_named(@src, @placeholders, named_values)
data/lib/cecil/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cecil
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.5"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cecil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Nicholaides
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-22 00:00:00.000000000 Z
11
+ date: 2024-03-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  An experimental templating library designed specifically for generating source code (especially for languages that
@@ -36,6 +36,7 @@ files:
36
36
  - lib/cecil/code.rb
37
37
  - lib/cecil/content_for.rb
38
38
  - lib/cecil/indentation.rb
39
+ - lib/cecil/lang/rust.rb
39
40
  - lib/cecil/lang/typescript.rb
40
41
  - lib/cecil/node.rb
41
42
  - lib/cecil/placeholder.rb