11const Iterator = @This ();
22
33const std = @import ("std" );
4+ const assert = std .debug .assert ;
45const ziggy = @import ("ziggy" );
56const superhtml = @import ("superhtml" );
67const scripty = @import ("scripty" );
8+ const zeit = @import ("zeit" );
79const context = @import ("../context.zig" );
810const doctypes = @import ("doctypes.zig" );
911const Signature = doctypes .Signature ;
@@ -25,7 +27,8 @@ _superhtml_context: superhtml.utils.IteratorContext(Value) = .{},
2527_impl : Impl ,
2628
2729pub const Impl = union (enum ) {
28- value_it : SliceIterator (Value ),
30+ slice_it : SliceIterator (Value ),
31+ leaves_it : LeavesIterator ,
2932
3033 pub fn len (impl : Impl ) usize {
3134 switch (impl ) {
@@ -37,6 +40,7 @@ pub const Impl = union(enum) {
3740pub fn init (gpa : Allocator , impl : Impl ) ! * Iterator {
3841 const res = try gpa .create (Iterator );
3942 res .* = .{ ._impl = impl , .len = impl .len () };
43+ res .last = 0 == res .len ;
4044 return res ;
4145}
4246
@@ -45,21 +49,24 @@ pub fn deinit(iter: *const Iterator, gpa: Allocator) void {
4549}
4650
4751pub fn next (iter : * Iterator , gpa : Allocator ) ! bool {
52+ if (iter .last ) return false ;
53+
4854 switch (iter ._impl ) {
4955 inline else = > | * v | {
50- const item = try v .next (gpa );
51- iter .it = try Value .from (gpa , item orelse return false );
52- iter .idx += 1 ;
53- iter .first = iter .idx == 1 ;
54- iter .last = iter .idx == iter .len ;
55- return true ;
56+ const item = try v .next (iter .idx , gpa );
57+ iter .it = try Value .from (gpa , item );
5658 },
5759 }
60+
61+ iter .idx += 1 ;
62+ iter .first = iter .idx == 1 ;
63+ iter .last = iter .idx >= iter .len ;
64+ return true ;
5865}
5966
6067pub fn fromArray (gpa : Allocator , arr : Array ) ! * Iterator {
6168 return init (gpa , .{
62- .value_it = .{ .items = arr ._items },
69+ .slice_it = .{ .items = arr ._items },
6370 });
6471}
6572
@@ -82,6 +89,7 @@ pub const Fields = struct {
8289 \\True on the last iteration loop.
8390 ;
8491};
92+
8593pub const Builtins = struct {
8694 pub const up = struct {
8795 pub const signature : Signature = .{ .ret = .Iterator };
@@ -107,18 +115,71 @@ pub const Builtins = struct {
107115
108116fn SliceIterator (comptime Element : type ) type {
109117 return struct {
110- idx : usize = 0 ,
111118 items : []const Element ,
112119
113120 pub fn len (self : @This ()) usize {
114121 return self .items .len ;
115122 }
116123
117- pub fn next (self : * @This (), gpa : Allocator ) ! ? Element {
124+ pub fn next (self : * @This (), idx : usize , gpa : Allocator ) ! Element {
118125 _ = gpa ;
119- if (self .idx == self .items .len ) return null ;
120- defer self .idx += 1 ;
121- return self .items [self .idx ];
126+ return self .items [idx ];
122127 }
123128 };
124129}
130+
131+ pub const LeavesIterator = struct {
132+ limit : u32 ,
133+ sections : []Section ,
134+ pages : []Page ,
135+
136+ pub const Section = struct {
137+ idx : u32 = 0 , // cursor into `page_indexes`
138+ page_indexes : []const u32 , // index into pages
139+ };
140+
141+ pub fn init (limit : u32 , sections : []Section , pages : []Page ) LeavesIterator {
142+ return .{
143+ .limit = limit ,
144+ .sections = sections ,
145+ .pages = pages ,
146+ };
147+ }
148+
149+ pub fn len (lit : * const LeavesIterator ) usize {
150+ return lit .limit ;
151+ }
152+
153+ pub fn next (lit : * LeavesIterator , idx : usize , gpa : Allocator ) ! * context.Page {
154+ assert (idx < lit .limit );
155+ _ = gpa ;
156+
157+ var next_page_date = context .DateTime .epoch ;
158+ var next_page : * context.Page = undefined ;
159+ var next_section_idx : usize = undefined ;
160+
161+ for (lit .sections , 0.. ) | * s , section_idx | {
162+ if (s .idx == s .page_indexes .len ) continue ;
163+
164+ while (true ) {
165+ const page_idx = s .page_indexes [s .idx ];
166+ const page = & lit .pages [page_idx ];
167+ if (! page ._parse .active ) {
168+ s .idx += 1 ;
169+ continue ;
170+ }
171+
172+ if (page .date ._inst .timestamp >= next_page_date .timestamp ) {
173+ next_page_date = page .date ._inst ;
174+ next_page = page ;
175+ next_section_idx = section_idx ;
176+ }
177+
178+ break ;
179+ }
180+ }
181+
182+ lit .sections [next_section_idx ].idx += 1 ;
183+ return next_page ;
184+ }
185+ };
0 commit comments