summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2020-03-08 09:06:03 +0100
committerYorhel <git@yorhel.nl>2020-03-08 09:11:48 +0100
commit220dfdad9046631bb94f839ea3949daef1c6229e (patch)
treee30bc7779be1b27d4f7932e5fa2dcc63d526eae0 /lib
parent141d1317ff1edaec3ad330590e41335687dfd69a (diff)
refactor: Add elm_empty() function to initialize a new form
This gets rid of the separate Elm-based empty form initialization and the ReleaseEdit.New module. There's rather less repitition with this approach. This is an alternative to the approach I implemented in 255dc704f4675326ebf6358c79b5b37fca903e4b - there I mentioned creating such a data structure in Perl as "tricky", which I thought it was, except it turns out to be pretty easy to automate in a reliable way. I'll convert the StaffEdit form to use this approach as well, after testing this approach a bit more.
Diffstat (limited to 'lib')
-rw-r--r--lib/VNDB/ExtLinks.pm16
-rw-r--r--lib/VNWeb/Elm.pm26
-rw-r--r--lib/VNWeb/Releases/Edit.pm72
3 files changed, 57 insertions, 57 deletions
diff --git a/lib/VNDB/ExtLinks.pm b/lib/VNDB/ExtLinks.pm
index 534d47dc..9f719a4d 100644
--- a/lib/VNDB/ExtLinks.pm
+++ b/lib/VNDB/ExtLinks.pm
@@ -6,7 +6,7 @@ use VNDB::Config;
use VNDB::Schema;
use Exporter 'import';
-our @EXPORT = ('enrich_extlinks', 'revision_extlinks', 'validate_extlinks', 'empty_extlinks');
+our @EXPORT = ('enrich_extlinks', 'revision_extlinks', 'validate_extlinks');
# column name in wikidata table => \%info
@@ -308,20 +308,6 @@ sub validate_extlinks {
}
-# Generate a struct with empty/default values according to the structure defined in validate_extlinks().
-sub empty_extlinks {
- my($type) = @_;
- my($schema) = grep +($_->{dbentry_type}||'') eq $type, values VNDB::Schema::schema->%*;
- +{
- map {
- my($f, $p) = ($_, $LINKS{$type}{$_});
- my($s) = grep $_->{name} eq $f, $schema->{cols}->@*;
- ($f, $s->{type} =~ /\[\]/ ? [] : $s->{type} =~ /^int/ ? 0 : '')
- } grep $LINKS{$type}{$_}{regex}, keys $LINKS{$type}->%*
- }
-}
-
-
# Returns a list of sites for use in VNWeb::Elm:
# { id => $id, name => $label, fmt => $label, regex => $regex, int => $bool, multi => $bool, default => 0||'""'||'[]', pattern => [..] }
sub extlinks_sites {
diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm
index 1500e80b..106f3d8d 100644
--- a/lib/VNWeb/Elm.pm
+++ b/lib/VNWeb/Elm.pm
@@ -21,7 +21,7 @@ use VNDB::ExtLinks ();
use VNWeb::Auth;
our @EXPORT = qw/
- elm_api
+ elm_api elm_empty
/;
@@ -258,6 +258,27 @@ sub elm_api {
}
+# Return a new, empty value that conforms to the given schema and can be parsed
+# by the generated Elm/json decoder for the same schema. It may not actually
+# validate according to the schema (e.g. required fields may be left empty).
+# Values are initialized as follows:
+# - If a 'default' has been set in the schema, that will be used.
+# - Nullable fields are initialized to undef
+# - Integers are initialized to 0
+# - Strings are initialized to ""
+# - Arrays are initialized to []
+sub elm_empty {
+ my($schema) = @_;
+ $schema = $schema->analyze if ref $schema eq 'TUWF::Validate';
+ return $schema->{default} if exists $schema->{default};
+ return undef if !$schema->{required};
+ return [] if $schema->{type} eq 'array';
+ return '' if $schema->{type} eq 'bool' || $schema->{type} eq 'scalar';
+ return 0 if $schema->{type} eq 'num' || $schema->{type} eq 'int';
+ return +{ map +($_, elm_empty($schema->{keys}{$_})), $schema->{keys} ? $schema->{keys}->%* : () } if $schema->{type} eq 'hash';
+ die "Unable to initialize required value of type '$schema->{type}' without a default";
+}
+
# Generate the Gen.Api module with the Response type and decoder.
sub write_api {
@@ -369,9 +390,6 @@ sub write_extlinks {
'patt = ['.join(', ', map string($_), $l->{pattern}->@*).']'
)."\n }";
} @links;
-
- $data .= def $name.'New' => $type =>
- "\n { ".join("\n , ", map sprintf('%-10s = %s', $_->{id}, $_->{default}), @links)."\n }";
}
links release => 'GRE.RecvExtlinks' => VNDB::ExtLinks::extlinks_sites('r');
diff --git a/lib/VNWeb/Releases/Edit.pm b/lib/VNWeb/Releases/Edit.pm
index c8ef02d4..7471972e 100644
--- a/lib/VNWeb/Releases/Edit.pm
+++ b/lib/VNWeb/Releases/Edit.pm
@@ -4,46 +4,46 @@ use VNWeb::Prelude;
my $FORM = {
- id => { _when => 'cmp in out', required => 0, id => 1 },
- title => { _when => 'cmp in out new', maxlength => 250 },
- original => { _when => 'cmp in out new', required => 0, default => '', maxlength => 250 },
- rtype => { _when => 'cmp in out', enum => \%RELEASE_TYPE },
- patch => { _when => 'cmp in out', anybool => 1 },
- freeware => { _when => 'cmp in out', anybool => 1 },
- doujin => { _when => 'cmp in out', anybool => 1 },
- lang => { _when => 'cmp in out', aoh => { lang => { enum => \%LANGUAGE } } },
- platforms => { _when => 'cmp in out', aoh => { platform => { enum => \%PLATFORM } } },
- media => { _when => 'cmp in out', aoh => {
+ id => { required => 0, id => 1 },
+ title => { maxlength => 250 },
+ original => { required => 0, default => '', maxlength => 250 },
+ rtype => { default => 'complete', enum => \%RELEASE_TYPE },
+ patch => { anybool => 1 },
+ freeware => { anybool => 1 },
+ doujin => { anybool => 1 },
+ lang => { aoh => { lang => { enum => \%LANGUAGE } } },
+ platforms => { aoh => { platform => { enum => \%PLATFORM } } },
+ media => { aoh => {
medium => { enum => \%MEDIUM },
qty => { uint => 1, range => [0,20] },
} },
- gtin => { _when => 'cmp in out', gtin => 1 },
- catalog => { _when => 'cmp in out', required => 0, default => '', maxlength => 50 },
- released => { _when => 'cmp in out', min => 1, rdate => 1 },
- minage => { _when => 'cmp in out', int => 1, enum => \%AGE_RATING },
- uncensored => { _when => 'cmp in out', anybool => 1 },
- resolution => { _when => 'cmp in out', enum => \%RESOLUTION },
- voiced => { _when => 'cmp in out', uint => 1, enum => \%VOICED },
- ani_story => { _when => 'cmp in out', uint => 1, enum => \%ANIMATED },
- ani_ero => { _when => 'cmp in out', uint => 1, enum => \%ANIMATED },
- website => { _when => 'cmp in out', required => 0, default => '', weburl => 1 },
- engine => { _when => 'cmp in out', required => 0, default => '', maxlength => 50 },
- extlinks => { _when => 'cmp in out', validate_extlinks('r')->%* },
- notes => { _when => 'cmp in out', required => 0, default => '', maxlength => 10240 },
- vn => { _when => 'cmp in out new', sort_keys => 'vid', aoh => {
+ gtin => { gtin => 1 },
+ catalog => { required => 0, default => '', maxlength => 50 },
+ released => { default => 99999999, min => 1, rdate => 1 },
+ minage => { int => 1, enum => \%AGE_RATING },
+ uncensored => { anybool => 1 },
+ resolution => { default => 'unknown', enum => \%RESOLUTION },
+ voiced => { uint => 1, enum => \%VOICED },
+ ani_story => { uint => 1, enum => \%ANIMATED },
+ ani_ero => { uint => 1, enum => \%ANIMATED },
+ website => { required => 0, default => '', weburl => 1 },
+ engine => { required => 0, default => '', maxlength => 50 },
+ extlinks => validate_extlinks('r'),
+ notes => { required => 0, default => '', maxlength => 10240 },
+ vn => { sort_keys => 'vid', aoh => {
vid => { id => 1 },
- title => { _when => 'out new' },
+ title => { _when => 'out' },
} },
- producers => { _when => 'cmp in out', sort_keys => 'pid', aoh => {
+ producers => { sort_keys => 'pid', aoh => {
pid => { id => 1 },
developer => { anybool => 1 },
publisher => { anybool => 1 },
name => { _when => 'out' },
} },
- hidden => { _when => 'cmp in out', anybool => 1 },
- locked => { _when => 'cmp in out', anybool => 1 },
+ hidden => { anybool => 1 },
+ locked => { anybool => 1 },
- engines => { _when => 'out new', aoh => {
+ engines => { _when => 'out', aoh => {
engine => {},
count => { uint => 1 },
} },
@@ -53,7 +53,6 @@ my $FORM = {
my $FORM_OUT = form_compile out => $FORM;
my $FORM_IN = form_compile in => $FORM;
-my $FORM_NEW = form_compile new => $FORM;
my $FORM_CMP = form_compile cmp => $FORM;
sub to_extlinks { $_[0]{extlinks} = { map +($_, delete $_[0]{$_}), grep /^l_/, keys $_[0]->%* } }
@@ -80,17 +79,13 @@ TUWF::get qr{/$RE{rrev}/(?<action>edit|copy)} => sub {
enrich_merge vid => 'SELECT id AS vid, title FROM vn WHERE id IN', $e->{vn};
enrich_merge pid => 'SELECT id AS pid, name FROM producers WHERE id IN', $e->{producers};
- if($copy) {
- $e->{gtin} = 0;
- $e->{catalog} = '';
- $e->{extlinks} = empty_extlinks 'r';
- }
+ $e->@{qw/gtin catalog extlinks/} = elm_empty($FORM_OUT)->@{qw/gtin catalog extlinks/} if $copy;
my $title = ($copy ? 'Copy ' : 'Edit ').$e->{title};
framework_ title => $title, type => 'r', dbobj => $e, tab => tuwf->capture('action'),
sub {
editmsg_ r => $e, $title, $copy;
- elm_ 'ReleaseEdit.Main' => $FORM_OUT, $copy ? {%$e, id=>undef} : $e;
+ elm_ ReleaseEdit => $FORM_OUT, $copy ? {%$e, id=>undef} : $e;
};
};
@@ -123,7 +118,8 @@ TUWF::get qr{/$RE{vid}/add}, sub {
}
} if @$delrel;
- elm_ 'ReleaseEdit.New' => $FORM_NEW, {
+ elm_ ReleaseEdit => $FORM_OUT, {
+ elm_empty($FORM_OUT)->%*,
title => $v->{title},
original => $v->{original},
engines => engines(),
@@ -162,7 +158,7 @@ elm_api ReleaseEdit => $FORM_OUT, $FORM_IN, sub {
my($id,undef,$rev) = db_edit r => $e->{id}, $data;
elm_Redirect "/r$id.$rev";
-}, New => $FORM_NEW;
+};
1;