Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add camomile-embedded package with compile-time data embedding#12

Open
toots wants to merge 1 commit into
mainfrom
embed-data
Open

Add camomile-embedded package with compile-time data embedding#12
toots wants to merge 1 commit into
mainfrom
embed-data

Conversation

@toots
Copy link
Copy Markdown
Member

@toots toots commented Apr 19, 2026

Adds a new camomile-embedded opam package. It provides the same API as camomile but with all Unicode data files (database, charmaps, locales, mappings) embedded directly into the library at compile time using ocaml-crunch. Programs linking against it have no runtime filesystem dependency on data files.

Changes

New camomile-embedded package (camomile-embedded.opam, src/embedded/, dune-project)
A new library built from camomile_embedded.ml + a crunch-generated embedded_data.ml. It defines a Config that reads data from the in-memory crunch table instead of the filesystem, then instantiates Camomile.Make(Config).

Database.Make functor (src/internal/database.ml, src/internal/database.mli)
Replaces the single hardcoded filesystem read with a FileReader module type and a Make functor. Database.Filesystem (the default) reads from disk as before. The embedded config supplies its own reader backed by crunch. The reader signature is (unit -> 'a) -> 'b so callers that return a different type from their intermediate representation (e.g. read_localedata) continue to work correctly.

val get in Config.Type (src/config.mli, src/configBase.ml, src/configImpl.dune.ml, src/toolslib/camomileconfig.ml)
Internal functors (Charmap.Configure, Unimap.Make, Unidata.Make) instantiate Database.Make(Config) so they pick up whichever reader the config provides.

Crunch rule (src/dune)
ocaml-crunch is invoked on a single root directory (the rule sandbox) rather than on each subdirectory separately, so keys include the subdirectory prefix (database/foo.mar, charmaps/bar.mar, etc.), matching the keys produced by Config.get. locales/*.mar is included alongside the other three directories.

Test (test/embedded/)
Exercises UTF-8, general category, NFC normalisation, and charmap round-trip entirely from embedded data, scoped to the camomile-embedded package.

@toots toots force-pushed the embed-data branch 4 times, most recently from 75384f2 to 0c51ee0 Compare April 19, 2026 17:17
Adds a new camomile-embedded opam package that embeds all Unicode data
(database, charmaps, locales, mappings) directly into the compiled
library using ocaml-crunch, eliminating any runtime filesystem
dependency on installed data files.

Key design points:

- Database.Make functor with FileReader module type replaces the
  previous approach of a global mutable ref. The embedded reader is
  strictly contained in camomile_embedded.ml with no global state.

- val get is added to Config.Type. Internal functors (Charmap.Configure,
  Unimap.Make, Unidata.Make) shadow Database with Database.Make(Config),
  picking up whatever reader the config provides.

- The reader signature is (unit -> 'a) -> 'b so both the filesystem
  path (input_value) and the embedded path (Marshal.from_string) go
  through the same reader function, preserving type safety across all
  call sites including read_localedata which returns a different type.

- The crunch rule passes a single root directory so keys include the
  subdirectory prefix (database/foo.mar, charmaps/bar.mar, etc.),
  matching what Filename.concat dir (fname ^ "." ^ suffix) produces in
  the embedded Config.get. locales/*.mar is also included.

- The embedded test is scoped to the camomile-embedded package so it
  does not run under a plain camomile build.
Comment thread src/dune
(write-file
%{target}
"\nlet prefix = \"%{env:CAMOMILE_PREFIX=/usr}/share/camomile\"\nlet datadir = Filename.concat prefix \"database\"\nlet localedir = Filename.concat prefix \"locales\"\nlet charmapdir = Filename.concat prefix \"charmaps\"\nlet unimapdir = Filename.concat prefix \"mappings\"\n")))
"\nlet prefix = \"%{env:CAMOMILE_PREFIX=/usr}/share/camomile\"\nlet datadir = Filename.concat prefix \"database\"\nlet localedir = Filename.concat prefix \"locales\"\nlet charmapdir = Filename.concat prefix \"charmaps\"\nlet unimapdir = Filename.concat prefix \"mappings\"\nlet get = CamomileLib.Database.Filesystem.get\n")))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be easier to write a small executable to do this rather than inline sources here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants