Hi everyone,
While developing my small app, I’m facing an issue that is sticking me.
The application draws KiCad electronic schematics, and for this, a module Painter
abstracts a canevas and the functions to draw on it:
module type Painter = sig
(** A module able to paint a canvas with several graphic primitives
and then to process the canvas into a picture file format. The
functions are supposed to be pure *)
(** the canvas of the painter *)
type t
val get_context : unit -> t
(** [get_context ()]
@return a new painting canvas *)
... primitives functions
end
This module was manipulated by the interpreter of a given version V5 of the schematic file. (No so) Recently, a new file format V6 for schematics was introduced. So I introduced a schematic painter type to abstract the schematic format:
module type SchPainter = sig
(** A module able to paint a schematic file in a painter context *)
(** the schematic context *)
type schContext
(** the underlying context *)
type painterContext
val initial_context : ?allow_missing_component:bool -> revision -> schContext
(** [initial_context allow_missing_component revision]
@return an new empty context *)
val parse_sheet : schContext -> String.t -> schContext
(** [parse_line content context] parse a [content] of schematic and
update [context].
@return the updated context *)
val output_context : schContext -> painterContext
(** [output_context context output] write the [context] as a image
format to [output] *)
end
Which are created via functors whose type is:
module type KicadSchHandler = sig
module MakeSchPainter: functor (P: Painter) -> SchPainter
end
Then I can create the two formats:
module MakeSchPainter (P : Painter) :
SchPainter with type painterContext = P.t = struct
type painterContext = P.t
... Implementation
end
So far, so good. But at some point, I create a SchPainter from a SvgPainter , and I want to get back the SVG content of the canevas as a string :
let schHandler =
if String.ends_with ~suffix:".sch" sch then
(module Kicadsch.V5: Kicadsch.Sigs.KicadSchHandler)
else if String.ends_with ~suffix:".kicad_sch" sch then
(module Kicadsch.V6: Kicadsch.Sigs.KicadSchHandler)
else
failwith ("unknown file extenstion for " ^ sch) in
let module SchPainter = (val schHandler) in
let module SvgSchModule = SchPainter.MakeSchPainter(SvgPainter) in
let open SvgSchModule in
let initctx = initial_context No_Rev in
let fileout = build_outputfilename outdir sch in
let%lwt o = Lwt_io.open_file ~mode:Lwt_io.Output fileout in
let%lwt i = Lwt_io.open_file ~mode:Lwt_io.Input sch in
let%lwt contents = Lwt_io.read i in
let endcontext = parse_sheet initctx contents in
let canvas = output_context endcontext in
let%lwt () = Lwt_io.write o (SvgPainter.write canvas) in
let%lwt () = Lwt_io.close i in
Lwt_io.close o
But the type checker chokes the line SvgPainter.write canvas
I understand that the functor eliminates the original painterContext
type in the generated SchPainter, but I don’t really see how to get it back for my own manipulation.