stash 1.0.0 → 2.0.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.
- data/ext/stash/build.c +267 -0
- data/ext/stash/execute.c +248 -0
- data/ext/stash/extconf.rb +3 -0
- data/ext/stash/intern.h +79 -0
- data/ext/stash/lex.yy.c +2143 -0
- data/ext/stash/lex.yy.h +333 -0
- data/ext/stash/mustache.c +50 -0
- data/ext/stash/mustache.h +124 -0
- data/ext/stash/optimize.c +208 -0
- data/ext/stash/stash.c +177 -0
- data/ext/stash/stash.h +17 -0
- data/ext/stash/tokens.c +151 -0
- data/ext/stash/types.c +181 -0
- data/lib/stash.rb +2 -34
- data/lib/stash/debug.rb +46 -0
- metadata +30 -88
- data/.document +0 -5
- data/LICENSE +0 -20
- data/README.markdown +0 -92
- data/Rakefile +0 -46
- data/VERSION +0 -1
- data/lib/stash/class_methods.rb +0 -59
- data/lib/stash/hash.rb +0 -62
- data/lib/stash/list.rb +0 -91
- data/lib/stash/redis_adapter.rb +0 -152
- data/lib/stash/string.rb +0 -16
- data/spec/hash_spec.rb +0 -29
- data/spec/list_spec.rb +0 -65
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -12
- data/spec/string_spec.rb +0 -9
- data/stash.gemspec +0 -68
data/ext/stash/types.c
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include "mustache.h"
|
3
|
+
#include "stash.h"
|
4
|
+
|
5
|
+
const size_t INITIAL_BUFFER_SIZE = 1024;
|
6
|
+
|
7
|
+
mustache_ruby_context_t* create_mustache_ruby_context()
|
8
|
+
{
|
9
|
+
mustache_ruby_context_t* r_ctx = mustache_malloc(sizeof(mustache_ruby_context_t));
|
10
|
+
r_ctx->buffer = rb_str_buf_new(INITIAL_BUFFER_SIZE);
|
11
|
+
r_ctx->buffer_length = 0;
|
12
|
+
return r_ctx;
|
13
|
+
}
|
14
|
+
|
15
|
+
void destroy_mustache_context(mustache_context_t* m_ctx)
|
16
|
+
{
|
17
|
+
mustache_free(m_ctx);
|
18
|
+
}
|
19
|
+
|
20
|
+
mustache_context_t* create_mustache_context(mustache_context_t* parent)
|
21
|
+
{
|
22
|
+
mustache_context_t* m_ctx = mustache_malloc(sizeof(mustache_context_t));
|
23
|
+
m_ctx->get_data = convert_type;
|
24
|
+
m_ctx->get_partial = get_partial;
|
25
|
+
m_ctx->parent = parent;
|
26
|
+
m_ctx->data = NULL;
|
27
|
+
m_ctx->partials = parent ? parent->partials : NULL;
|
28
|
+
m_ctx->prefix = parent ? parent->prefix : NULL;
|
29
|
+
m_ctx->custom = parent ? parent->custom : create_mustache_ruby_context();
|
30
|
+
m_ctx->debug_mode = parent ? parent->debug_mode : false;
|
31
|
+
m_ctx->destroy = destroy_mustache_context;
|
32
|
+
return m_ctx;
|
33
|
+
}
|
34
|
+
|
35
|
+
static void destroy_mustache_object(mustache_value_t* value)
|
36
|
+
{
|
37
|
+
mustache_value_t* m_value = (mustache_value_t*) value;
|
38
|
+
m_value->data.object->destroy(m_value->data.object);
|
39
|
+
mustache_free(m_value);
|
40
|
+
}
|
41
|
+
|
42
|
+
static mustache_value_t* create_mustache_object(
|
43
|
+
mustache_context_t* m_ctx,
|
44
|
+
VALUE object)
|
45
|
+
{
|
46
|
+
mustache_value_t* val = mustache_malloc(sizeof(mustache_value_t));
|
47
|
+
val->type = VALUE_OBJECT;
|
48
|
+
val->length = 0;
|
49
|
+
val->data.object = create_mustache_context(m_ctx);
|
50
|
+
val->data.object->data = (void*) object;
|
51
|
+
val->destroy = destroy_mustache_object;
|
52
|
+
return val;
|
53
|
+
}
|
54
|
+
|
55
|
+
static void destroy_mustache_list(mustache_value_t* value)
|
56
|
+
{
|
57
|
+
mustache_context_t** m_list_ctxs = value->data.list;
|
58
|
+
for (size_t i = 0; i < value->length; i++) {
|
59
|
+
m_list_ctxs[i]->destroy(m_list_ctxs[i]);
|
60
|
+
}
|
61
|
+
mustache_free(value);
|
62
|
+
}
|
63
|
+
|
64
|
+
static mustache_value_t* create_mustache_list(
|
65
|
+
mustache_context_t* m_ctx,
|
66
|
+
VALUE rb_array)
|
67
|
+
{
|
68
|
+
size_t length = RARRAY_LEN(rb_array);
|
69
|
+
mustache_context_t** m_list_ctxs = mustache_malloc(sizeof(mustache_context_t*) * length);
|
70
|
+
|
71
|
+
for (long i = 0; i < length; i++) {
|
72
|
+
m_list_ctxs[i] = create_mustache_context(m_ctx);
|
73
|
+
m_list_ctxs[i]->data = (void*) rb_ary_entry(rb_array, i);
|
74
|
+
}
|
75
|
+
|
76
|
+
mustache_value_t* val = mustache_malloc(sizeof(mustache_value_t));
|
77
|
+
val->type = VALUE_LIST;
|
78
|
+
val->length = length;
|
79
|
+
val->data.list = m_list_ctxs;
|
80
|
+
val->destroy = destroy_mustache_list;
|
81
|
+
return val;
|
82
|
+
}
|
83
|
+
|
84
|
+
static void destroy_mustache_value(mustache_value_t* value)
|
85
|
+
{
|
86
|
+
mustache_free(value);
|
87
|
+
}
|
88
|
+
|
89
|
+
static mustache_value_t* create_mustache_value(
|
90
|
+
mustache_context_t* m_ctx,
|
91
|
+
VALUE rb_string)
|
92
|
+
{
|
93
|
+
mustache_value_t* val = mustache_malloc(sizeof(mustache_value_t));
|
94
|
+
val->type = VALUE_VALUE;
|
95
|
+
val->data.value = rb_string == Qnil ? NULL : RSTRING_PTR(rb_string);
|
96
|
+
val->length = rb_string == Qnil ? 0 : RSTRING_LEN(rb_string);
|
97
|
+
val->destroy = destroy_mustache_value;
|
98
|
+
return val;
|
99
|
+
}
|
100
|
+
|
101
|
+
static mustache_value_t* convert_value(
|
102
|
+
VALUE rb_value,
|
103
|
+
mustache_context_t* m_ctx)
|
104
|
+
{
|
105
|
+
switch (TYPE(rb_value)) {
|
106
|
+
case T_OBJECT: return create_mustache_object(m_ctx, rb_value);
|
107
|
+
case T_STRUCT: return create_mustache_object(m_ctx, rb_value);
|
108
|
+
case T_HASH: return create_mustache_object(m_ctx, rb_value);
|
109
|
+
case T_TRUE: return create_mustache_value(m_ctx, rb_str_new2("true"));
|
110
|
+
case T_FALSE: return create_mustache_value(m_ctx, Qnil);
|
111
|
+
case T_NONE: return create_mustache_value(m_ctx, Qnil);
|
112
|
+
case T_NIL: return create_mustache_value(m_ctx, Qnil);
|
113
|
+
case T_FLOAT: return create_mustache_value(m_ctx, rb_funcall(rb_value, rb_intern("to_s"), 0, 0));
|
114
|
+
case T_STRING: return create_mustache_value(m_ctx, rb_value);
|
115
|
+
case T_FIXNUM: return create_mustache_value(m_ctx, rb_fix2str(rb_value, 10));
|
116
|
+
case T_BIGNUM: return create_mustache_value(m_ctx, rb_big2str(rb_value, 10));
|
117
|
+
case T_ARRAY: return create_mustache_list(m_ctx, rb_value);
|
118
|
+
default:
|
119
|
+
if (rb_class_of(rb_value) == rb_cProc) {
|
120
|
+
return convert_value(rb_funcall(rb_value, rb_intern("call"), 0, 0), m_ctx);
|
121
|
+
}
|
122
|
+
return create_mustache_value(m_ctx, rb_any_to_s(rb_value));
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
static mustache_value_t* convert_hash(
|
127
|
+
VALUE hash,
|
128
|
+
char* key,
|
129
|
+
mustache_context_t* m_lookup_context,
|
130
|
+
mustache_context_t* m_exection_context)
|
131
|
+
{
|
132
|
+
VALUE rb_value;
|
133
|
+
if (NIL_P(rb_value = rb_hash_aref(hash, ID2SYM(rb_intern(key))))) {
|
134
|
+
return NULL;
|
135
|
+
}
|
136
|
+
return convert_value(rb_value, m_lookup_context);
|
137
|
+
}
|
138
|
+
|
139
|
+
static mustache_value_t* convert_object(
|
140
|
+
VALUE rb_object,
|
141
|
+
char* key,
|
142
|
+
mustache_context_t* m_lookup_context,
|
143
|
+
mustache_context_t* m_exection_context)
|
144
|
+
{
|
145
|
+
ID id = rb_intern(key);
|
146
|
+
if (rb_respond_to(rb_object, id)) {
|
147
|
+
rb_ivar_set(rb_object, rb_intern("@context"), (VALUE) m_exection_context->data);
|
148
|
+
|
149
|
+
double start = 0;
|
150
|
+
if (m_lookup_context->debug_mode) {
|
151
|
+
start = get_time();
|
152
|
+
}
|
153
|
+
|
154
|
+
VALUE result = rb_funcall(rb_object, id, 0, 0);
|
155
|
+
|
156
|
+
if (m_lookup_context->debug_mode) {
|
157
|
+
log_ruby_callback_execution_time(m_lookup_context, id, get_time() - start);
|
158
|
+
}
|
159
|
+
|
160
|
+
return convert_value(result, m_lookup_context);
|
161
|
+
}
|
162
|
+
return NULL;
|
163
|
+
}
|
164
|
+
|
165
|
+
mustache_value_t* convert_type(
|
166
|
+
char* key,
|
167
|
+
void* context,
|
168
|
+
mustache_context_t* m_lookup_context,
|
169
|
+
mustache_context_t* m_exection_context)
|
170
|
+
{
|
171
|
+
if (strcmp(key, ".") == 0) {
|
172
|
+
return convert_value((VALUE)context, m_lookup_context);
|
173
|
+
}
|
174
|
+
|
175
|
+
VALUE rb_context = (VALUE) context;
|
176
|
+
switch (TYPE(rb_context)) {
|
177
|
+
case T_OBJECT: return convert_object(rb_context, key, m_lookup_context, m_exection_context);
|
178
|
+
case T_HASH: return convert_hash(rb_context, key, m_lookup_context, m_exection_context);
|
179
|
+
default: return NULL;
|
180
|
+
}
|
181
|
+
}
|
data/lib/stash.rb
CHANGED
@@ -1,34 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
attr_reader :adapter
|
4
|
-
|
5
|
-
# Timeout when performing a blocking action, such as blocking pop
|
6
|
-
class TimeoutError < StandardError; end
|
7
|
-
|
8
|
-
def initialize(config)
|
9
|
-
raise ArgumentError, "no adapter specified" unless config[:adapter]
|
10
|
-
@adapter = Stash.adapter_class(config[:adapter]).new config
|
11
|
-
end
|
12
|
-
|
13
|
-
# Store an object in the Stash
|
14
|
-
def []=(key, value)
|
15
|
-
@adapter[key.to_s] = value
|
16
|
-
end
|
17
|
-
|
18
|
-
# Retrieve an object from the Stash
|
19
|
-
def [](key)
|
20
|
-
@adapter[key.to_s]
|
21
|
-
end
|
22
|
-
|
23
|
-
# Remove a key from the Stash
|
24
|
-
def delete(key)
|
25
|
-
@adapter.delete(key.to_s)
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
require 'stash/class_methods'
|
31
|
-
require 'stash/redis_adapter'
|
32
|
-
require 'stash/string'
|
33
|
-
require 'stash/list'
|
34
|
-
require 'stash/hash'
|
1
|
+
require 'stash/stash'
|
2
|
+
require 'stash/debug'
|
data/lib/stash/debug.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
class Template::Callback
|
2
|
+
attr_accessor :name
|
3
|
+
attr_accessor :time
|
4
|
+
|
5
|
+
def initialize(name, time)
|
6
|
+
@name = name
|
7
|
+
@time = time
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
"['#{@name}', #{@time}],"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Template::Debug
|
16
|
+
attr_accessor :total_time
|
17
|
+
attr_accessor :callbacks
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@callbacks = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_callback(name, time)
|
24
|
+
@callbacks.push Template::Callback.new(name, time)
|
25
|
+
end
|
26
|
+
|
27
|
+
def slowest_callbacks(n)
|
28
|
+
@callbacks.sort { |a, b| b.time <=> a.time}.first(n)
|
29
|
+
end
|
30
|
+
|
31
|
+
def group_slowest_callbacks(n)
|
32
|
+
@callbacks.group_by(&:name) \
|
33
|
+
.map { |k, v| [ k, v.inject(0) { |sum, x| sum + x.time }, v.length ] } \
|
34
|
+
.sort { |a, b| b[1] <=> a[1] } \
|
35
|
+
.first(n)
|
36
|
+
end
|
37
|
+
|
38
|
+
def mustache_time
|
39
|
+
total_time - ruby_time
|
40
|
+
end
|
41
|
+
|
42
|
+
def ruby_time
|
43
|
+
@callbacks.inject(0) { |sum, x| sum + x.time }
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
metadata
CHANGED
@@ -1,100 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 23
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
|
-
-
|
6
|
+
- 2
|
8
7
|
- 0
|
9
8
|
- 0
|
10
|
-
version:
|
9
|
+
version: 2.0.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
|
-
-
|
12
|
+
- J.P. Cummins
|
14
13
|
autorequire:
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2012-06-24 00:00:00 -07:00
|
19
18
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 11
|
30
|
-
segments:
|
31
|
-
- 2
|
32
|
-
- 1
|
33
|
-
- 0
|
34
|
-
version: 2.1.0
|
35
|
-
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: redis-namespace
|
39
|
-
prerelease: false
|
40
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
hash: 55
|
46
|
-
segments:
|
47
|
-
- 0
|
48
|
-
- 10
|
49
|
-
- 0
|
50
|
-
version: 0.10.0
|
51
|
-
type: :runtime
|
52
|
-
version_requirements: *id002
|
53
|
-
- !ruby/object:Gem::Dependency
|
54
|
-
name: rspec
|
55
|
-
prerelease: false
|
56
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
hash: 7
|
62
|
-
segments:
|
63
|
-
- 2
|
64
|
-
- 2
|
65
|
-
- 0
|
66
|
-
version: 2.2.0
|
67
|
-
type: :development
|
68
|
-
version_requirements: *id003
|
69
|
-
description: Stash maps the facilities provided by data structures servers onto classes which mimic Ruby's built-in types
|
70
|
-
email: tony@medioh.com
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: stash, a lower-level mustache
|
22
|
+
email: jpcummins@gmail.com
|
71
23
|
executables: []
|
72
24
|
|
73
|
-
extensions:
|
25
|
+
extensions:
|
26
|
+
- ext/stash/extconf.rb
|
27
|
+
extra_rdoc_files: []
|
74
28
|
|
75
|
-
extra_rdoc_files:
|
76
|
-
- LICENSE
|
77
|
-
- README.markdown
|
78
29
|
files:
|
79
|
-
- .
|
80
|
-
- LICENSE
|
81
|
-
- README.markdown
|
82
|
-
- Rakefile
|
83
|
-
- VERSION
|
30
|
+
- lib/stash/debug.rb
|
84
31
|
- lib/stash.rb
|
85
|
-
-
|
86
|
-
-
|
87
|
-
-
|
88
|
-
-
|
89
|
-
-
|
90
|
-
-
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
- stash.
|
32
|
+
- ext/stash/build.c
|
33
|
+
- ext/stash/execute.c
|
34
|
+
- ext/stash/lex.yy.c
|
35
|
+
- ext/stash/mustache.c
|
36
|
+
- ext/stash/optimize.c
|
37
|
+
- ext/stash/stash.c
|
38
|
+
- ext/stash/tokens.c
|
39
|
+
- ext/stash/types.c
|
40
|
+
- ext/stash/intern.h
|
41
|
+
- ext/stash/lex.yy.h
|
42
|
+
- ext/stash/mustache.h
|
43
|
+
- ext/stash/stash.h
|
44
|
+
- ext/stash/extconf.rb
|
96
45
|
has_rdoc: true
|
97
|
-
homepage:
|
46
|
+
homepage: https://github.com/jpcummins/stash
|
98
47
|
licenses: []
|
99
48
|
|
100
49
|
post_install_message:
|
@@ -103,32 +52,25 @@ rdoc_options: []
|
|
103
52
|
require_paths:
|
104
53
|
- lib
|
105
54
|
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
55
|
requirements:
|
108
56
|
- - ">="
|
109
57
|
- !ruby/object:Gem::Version
|
110
|
-
hash: 3
|
111
58
|
segments:
|
112
59
|
- 0
|
113
60
|
version: "0"
|
114
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
62
|
requirements:
|
117
63
|
- - ">="
|
118
64
|
- !ruby/object:Gem::Version
|
119
|
-
hash: 3
|
120
65
|
segments:
|
121
66
|
- 0
|
122
67
|
version: "0"
|
123
68
|
requirements: []
|
124
69
|
|
125
70
|
rubyforge_project:
|
126
|
-
rubygems_version: 1.3.
|
71
|
+
rubygems_version: 1.3.6
|
127
72
|
signing_key:
|
128
73
|
specification_version: 3
|
129
|
-
summary:
|
130
|
-
test_files:
|
131
|
-
|
132
|
-
- spec/list_spec.rb
|
133
|
-
- spec/spec_helper.rb
|
134
|
-
- spec/string_spec.rb
|
74
|
+
summary: High perfomance mustache rendering engine written in C with extensions for Ruby
|
75
|
+
test_files: []
|
76
|
+
|
data/.document
DELETED
data/LICENSE
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
Copyright (c) 2009 Tony Arcieri
|
2
|
-
|
3
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
10
|
-
|
11
|
-
The above copyright notice and this permission notice shall be
|
12
|
-
included in all copies or substantial portions of the Software.
|
13
|
-
|
14
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|