use v6.e.PREVIEW; #| Post database unit module DB; use Pandoc; use JSON::Class:auth; #| Top level metadata for the blog class BlogMeta is json(:pretty) { #| The title of the blog has Str:D $.title is required; #| The tagline of the blog has Str:D $.tagline is required; } #| Shared post meta-data role Post is json { #| The location of the source file for the post has IO::Path:D $.source is required is json( :to-json(*.Str), :from-json(*.IO) ); #| The time to display for the creation of the post has DateTime:D $.posted-at is required is json( :to-json(*.Str), :from-json(*.DateTime) ); #| An optional list of edit times for the post has DateTime:D @.edited-at is json( :to-json( value => { $^value.Str } ), :from-json( value => { $^value.DateTime } ) ) = []; #| An optional list of extra slugs to use for this post has Str:D @.slugs is json = []; #| Should the post be hidden from the main list has Bool:D $.hidden is json is rw = False; #| Get the title for this post, intended to be extracted from whatever #| document produced it method title(--> Str:D) {...} #| Get the list of slugs for this post, including ones auto generated from #| the title, as well as any additional slugs method all-slugs(--> Array[Str:D]) { my $long-title-slug = self.title.lc.subst: /\h*/, '-'; return [$long-title-slug, @!slugs].flat.Array; } } #| A plain markdown post class MarkdownPost does Post is json { #| Marker for disambiguation between post types in json representation, the #| cheaty way has Bool:D $.markdown = True; method title(--> Str:D) { markdown-title($!source) } } # #| A literate idris post in markdown format # class IdrisPost does Post { # method title(--> Str:D) { # markdown-title($!source) # } # } #| The top level posts database class PostDB is json(:pretty) { #| The metadat for the blog has BlogMeta:D $.meta is required; #| A mapping from post ids to posts has %.posts{Int:D} of MarkdownPost:D = %(); #| Get the next unused post ID method next-post-id(--> Int) { if %!posts { %!posts.keys.max + 1 } else { 0 } } #| Insert a new post to the DB, returning its id method insert-post(Post:D $post --> Int) { my $id = self.next-post-id; %!posts{$id} = $post; $id } }