1:- module(parse, [
    2              parse_upload_metadata/2
    3          ]).    4
    5:- use_module(library(when)).    6:- use_module(library(base64)).    7:- use_module(library(plunit)).    8/* parsing */
    9
   10assoc_metadata_parts([], []).
   11assoc_metadata_parts([Key-Value|Rest_A], [Meta|Rest_B]) :-
   12    when((   ground(Value)
   13         ;   ground(Value_base64)),
   14         base64_encoded(Value,Value_base64, [])),
   15    atomic_list_concat([Key,Value_base64], ' ', Meta),
   16    !,
   17    assoc_metadata_parts(Rest_A, Rest_B).
   18assoc_metadata_parts([Key|Rest_A], [Key|Rest_B]) :-
   19    assoc_metadata_parts(Rest_A, Rest_B).
   20
   21parse_upload_metadata(Atom, Assoc) :-
   22    when(
   23        (   ground(Assoc)
   24        ;   ground(Parts)),
   25        assoc_metadata_parts(Assoc, Parts)
   26    ),
   27    atomic_list_concat(Parts, ',', Atom).
   28
   29:- begin_tests(parse).   30
   31test(parse_upload_metadata, []) :-
   32    String = 'filename d29ybGRfZG9taW5hdGlvbl9wbGFuLnBkZg==,is_confidential',
   33    parse_upload_metadata(String, Struct),
   34    Struct = [filename-"world_domination_plan.pdf",is_confidential].
   35
   36test(parse_upload_metadata_backwards, []) :-
   37    Struct = [filename-"world_domination_plan.pdf",is_confidential],
   38    parse_upload_metadata(String, Struct),
   39    String = 'filename d29ybGRfZG9taW5hdGlvbl9wbGFuLnBkZg==,is_confidential'.
   40
   41test(parse_upload_metadata_backwards_empty, []) :-
   42    Struct = [filename-"world_domination_plan.pdf"],
   43    parse_upload_metadata(String, Struct),
   44    String = 'filename d29ybGRfZG9taW5hdGlvbl9wbGFuLnBkZg=='.
   45
   46:- end_tests(parse).