Skip to content

Commit 66dbe73

Browse files
committed
Add for_to_data combinators for archetypes
1 parent 5dbf5b8 commit 66dbe73

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

CHANGES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
- Add `Yocaml.Data.into` and `Yocaml.Data.Validation.from` helpers for easier module use (by [Linda-Njau](https://github.com/Linda-Njau))
1212
- Add `Yocaml.Metadata.Injectable` and `Yocaml.Metadata.Readable` functors to simplify creation of injectable and readable modules (by [Linda-Njau](https://github.com/Linda-Njau))
1313
- Add `Yocaml.Data.Validation.String`, a set of validator for `String` (by [Okhuomon Ajayi](https://github.com/six-shot))
14-
- Adds missing test coverage for `Nel.equal` and `Nel.append` functions (by [Bill Njoroge](https://github.com/Bnjoroge1))
14+
- Add missing test coverage for `Nel.equal` and `Nel.append` functions (by [Bill Njoroge](https://github.com/Bnjoroge1))
15+
- Add `to_data` and `from_data` for Archetypes (by [gr-im](https://github.com/xvw))
16+
17+
1518
### v2.6.0 2025-09-23 Nantes (France)
1619

1720
#### Yocaml

lib/core/archetype.ml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,12 @@ module Datetime = struct
119119
| None -> Data.Validation.fail_with ~given:str "Invalid date format"
120120
| Some (year, month, day) -> make ~year ~month ~day ()
121121

122-
let validate =
122+
let from_data =
123123
let open Data.Validation in
124124
string & (validate_from_datetime_str / validate_from_date_str)
125125

126+
let validate = from_data
127+
126128
let month_to_int = function
127129
| Jan -> 1
128130
| Feb -> 2
@@ -235,7 +237,7 @@ module Datetime = struct
235237
Format.fprintf ppf "%04d-%02d-%02dT%02d:%02d:%02d%s" dt.year mon dt.day
236238
dt.hour dt.min dt.sec tz
237239

238-
let normalize ({ year; month; day; hour; min; sec } as dt) =
240+
let to_data ({ year; month; day; hour; min; sec } as dt) =
239241
let has_time = not (Int.equal (compare_time dt dummy) 0) in
240242
let datetime_repr = Format.asprintf "%a" pp dt in
241243
let date_repr = Format.asprintf "%a" pp_date dt in
@@ -263,6 +265,8 @@ module Datetime = struct
263265
] )
264266
]
265267

268+
let normalize = to_data
269+
266270
module Infix = struct
267271
let ( = ) = equal
268272
let ( <> ) x y = not (equal x y)
@@ -325,6 +329,8 @@ module Page = struct
325329
let open Data.Validation in
326330
record validate_page
327331

332+
let from_data = validate
333+
328334
let to_meta name = function
329335
| None -> []
330336
| Some x ->
@@ -362,6 +368,7 @@ module Page = struct
362368

363369
let normalize_meta obj = Data.[ ("meta", list @@ meta_list obj) ]
364370
let normalize obj = normalize_parameters obj @ normalize_meta obj
371+
let to_data obj = Data.record (normalize obj)
365372
end
366373

367374
module Article = struct
@@ -408,6 +415,8 @@ module Article = struct
408415
and+ date = required fields "date" Datetime.validate in
409416
new article page ?synopsis ~title ~date ())
410417

418+
let from_data = validate
419+
411420
let normalize obj =
412421
Page.normalize obj
413422
@ Data.
@@ -417,6 +426,8 @@ module Article = struct
417426
; ("date", Datetime.normalize obj#date)
418427
; ("has_synopsis", bool @@ Option.is_some obj#synopsis)
419428
]
429+
430+
let to_data obj = Data.record (normalize obj)
420431
end
421432

422433
module Articles = struct
@@ -478,4 +489,6 @@ module Articles = struct
478489
("articles", list_of normalize_article obj#articles)
479490
:: ("has_articles", bool @@ not (is_empty_list obj#articles))
480491
:: Page.normalize obj
492+
493+
let to_data obj = Data.record (normalize obj)
481494
end

lib/core/archetype.mli

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,15 @@ module Datetime : sig
8989
(** [make ?time ~year ~month ~day ()] Builds a date when all data and
9090
validates all data.*)
9191

92-
val validate : Data.t -> t Data.Validation.validated_value
92+
include Data.Validation.S with type t := t
93+
94+
val validate : t Data.validable
9395
(** [validate data] try to read a date from a generic representation.*)
9496

9597
(** {1 Dealing with date as metadata} *)
9698

99+
include Data.S with type t := t
100+
97101
val normalize : t -> Data.t
98102
(** [normalize datetime] render data generically (with additional fields).
99103
Here is the list of fields:
@@ -227,6 +231,8 @@ module Page : sig
227231
228232
A page can be parsed and injected. *)
229233

234+
include Data.Validation.S with type t := t
235+
230236
include Required.DATA_READABLE with type t := t
231237
(** @inline *)
232238

@@ -239,6 +245,8 @@ module Page : sig
239245
description or charset with the parameters [has_page_title],
240246
[has_page_description], [has_page_charset] and [has_page_tags]. *)
241247

248+
include Data.S with type t := t
249+
242250
include Required.DATA_INJECTABLE with type t := t
243251
(** @inline *)
244252
end
@@ -270,13 +278,17 @@ module Article : sig
270278
metadata will use the article's [title]. The same applies to [description]
271279
and [synopsis]. *)
272280

281+
include Data.Validation.S with type t := t
282+
273283
include Required.DATA_READABLE with type t := t
274284
(** @inline *)
275285

276286
(** As an article is also a page, article-normalized data includes
277287
article-normalized data with additional fields. As with optional fields,
278288
[synopsis] has a [has_synopsis] version. *)
279289

290+
include Data.S with type t := t
291+
280292
include Required.DATA_INJECTABLE with type t := t
281293
(** @inline *)
282294
end
@@ -343,6 +355,8 @@ module Articles : sig
343355
(** Pipe {!val:fetch} into a computed page. You can refer to the examples to
344356
see how this is used in a classic pipeline. *)
345357

358+
include Data.S with type t := t
359+
346360
include Required.DATA_INJECTABLE with type t := t
347361
(** @inline *)
348362
end

0 commit comments

Comments
 (0)