Skip to content

Commit

Permalink
fix(dotnet): put back .NET resource map generation
Browse files Browse the repository at this point in the history
  • Loading branch information
krvital committed Oct 11, 2024
1 parent b56d072 commit fa0582e
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 7 deletions.
4 changes: 4 additions & 0 deletions src/aidbox_sdk/converter.clj
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@
(url->resource-name (:url schema)))
(safe-conj
(hash-map :base (get schema :base)
;; FIXME `id`and `kind` need only for .NET resource map generation
;; remove them from IR Schema after refactoring
:id (get schema :id)
:kind (get schema :kind)
:resource-name (url->resource-name (get schema :url))
:base-resource-name (when (get schema :base)
(url->resource-name (get schema :base)))
Expand Down
2 changes: 1 addition & 1 deletion src/aidbox_sdk/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
(save-files! (generator/generate-search-params generator' search-param-ir-schemas))

(println "Generating common SDK files")
(save-files! (generator/generate-sdk-files generator'))
(save-files! (generator/generate-sdk-files generator' ir-schemas))

(println "Finished succesfully!")
(println "Output dir: " (.getAbsolutePath output-dir))))
Expand Down
2 changes: 1 addition & 1 deletion src/aidbox_sdk/generator.clj
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
(generate-resource-module [this ir-schema])
(generate-search-params [this ir-schemas])
(generate-constraints [this ir-schemas])
(generate-sdk-files [this]))
(generate-sdk-files [this ir-schemas]))
62 changes: 60 additions & 2 deletions src/aidbox_sdk/generator/dotnet.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
[aidbox-sdk.generator.helpers :refer [->pascal-case uppercase-first-letter]]
[aidbox-sdk.generator.utils :as u]
[clojure.java.io :as io]
[clojure.string :as str])
[clojure.string :as str]
[aidbox-sdk.fhir :as fhir])
(:import
[aidbox_sdk.generator CodeGenerator]))

Expand Down Expand Up @@ -244,6 +245,60 @@
(io/file (package->directory (:package ir-schema))
(str (->pascal-case (:resource-name ir-schema)) ".cs")))

(defn generate-resource-map [schemas]
;; TODO refactor
;; The base or not base should be decided on converter layer
(->> schemas
(remove (fn [schema]
(fhir/primitive-type? schema)))
(map (fn [schema]
(assoc schema :base? (or (fhir/base-type? schema)
(and (fhir/datatype? schema)
(not (fhir/primitive-type? schema)))))))
(sort-by :base?)
(reverse)
(map (fn [schema]
(let [class-name' (class-name (:resource-name schema))
module-name (if (:base? schema)
"Base"
(package->module-name (:package schema)))]
(format "{ typeof(Aidbox.FHIR.%s.%s), \"%s\"}"
module-name
class-name'
class-name'))))))

(defn generate-utils-namespace [ir-schemas]
(str/join "\n" ["using System.Text.Json;"
"using System.Text.Json.Serialization;"
""
"namespace Aidbox.FHIR.Utils;"
""
"public interface IResource { string? Id { get; set; } }"
""
"public class LowercaseNamingPolicy : JsonNamingPolicy"
"{"
" public override string ConvertName(string name) => name.ToLower();"
"}"
""
"public class Config"
"{"
" public static readonly JsonSerializerOptions JsonSerializerOptions = new()"
" {"
" DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,"
" PropertyNamingPolicy = JsonNamingPolicy.CamelCase,"
" Converters = { new JsonStringEnumConverter(new LowercaseNamingPolicy()) },"
" WriteIndented = true"
" };"
""
" public static readonly Dictionary<Type, string> ResourceMap = new()"
" {"
(->> (generate-resource-map ir-schemas)
(map u/add-indent)
(map u/add-indent)
(str/join ",\n"))
" };"
"}"]))

(defrecord DotNetCodeGenerator []
CodeGenerator
(generate-datatypes [_ ir-schemas]
Expand Down Expand Up @@ -284,6 +339,9 @@
(assoc ir-schema :url (:url ir-schema)))})
constrained-ir-schemas))

(generate-sdk-files [_] (generator/prepare-sdk-files :dotnet)))
(generate-sdk-files [_ ir-schemas]
(let [common-sdk-files (generator/prepare-sdk-files :dotnet)
utils (generate-utils-namespace ir-schemas)]
(conj common-sdk-files {:path (io/file "Utils.cs") :content utils}))))

(def generator (->DotNetCodeGenerator))
2 changes: 1 addition & 1 deletion src/aidbox_sdk/generator/python.clj
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,6 @@
(map generate-class (:backbone-elements ir-schema)))])})
constraint-ir-schemas))

(generate-sdk-files [_] (generator/prepare-sdk-files :python)))
(generate-sdk-files [_ _] (generator/prepare-sdk-files :python)))

(def generator (->PythonCodeGenerator))
2 changes: 1 addition & 1 deletion src/aidbox_sdk/generator/typescript.clj
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,6 @@
(map generate-class (:backbone-elements ir-schema)))]})})
ir-schemas))

(generate-sdk-files [_] (generator/prepare-sdk-files :typescript)))
(generate-sdk-files [_ _] (generator/prepare-sdk-files :typescript)))

(def generator (->TypeScriptCodeGenerator))
4 changes: 3 additions & 1 deletion test/aidbox_sdk/converter_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@

(testing "convert constraint"
(is (= [(fixt/get-data :organization-preferred-contact-ir-schema)]
(sut/convert [(fixt/get-data :organization-preferred-contact-fhir-schema)])))))
(sut/convert [(fixt/get-data :organization-preferred-contact-fhir-schema)])

))))

(deftest test-apply-constraints
(testing "constraints"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
:name "Extension",
:type "Extension",
:fhir-version "hl7.fhir.r4.core"
:id "organization-preferredContact",
:kind "complex-type",
:resource-name "organization-preferred-Contact"
:elements
[{:name "url",
Expand Down
2 changes: 2 additions & 0 deletions test/aidbox_sdk/fixtures/schemas.clj
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,8 @@
{:package "hl7.fhir.r4.core",
:derivation "specialization",
:name "Patient",
:id "Patient",
:kind "resource",
:resource-name "Patient",
:type "Patient",
:elements
Expand Down
22 changes: 22 additions & 0 deletions test/aidbox_sdk/generator/dotnet_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,25 @@
{:path (io/file "hl7-fhir-r4-core/Patient.cs"),
:content
"using Aidbox.FHIR.Base;\nusing Aidbox.FHIR.Utils;\n\nnamespace Aidbox.FHIR.R4.Core;\n\npublic class Patient : DomainResource, IResource\n{\n public bool? MultipleBirthBoolean { get; set; }\n public Base.Address[]? Address { get; set; }\n public string? DeceasedDateTime { get; set; }\n public Base.ResourceReference? ManagingOrganization { get; set; }\n public bool? DeceasedBoolean { get; set; }\n public Base.HumanName[]? Name { get; set; }\n public string? BirthDate { get; set; }\n public int? MultipleBirthInteger { get; set; }\n public object? MultipleBirth \n {\n get\n {\n if (MultipleBirthBoolean is not null)\n {\n return MultipleBirthBoolean;\n }\n \n if (MultipleBirthInteger is not null)\n {\n return MultipleBirthInteger;\n }\n \n return null;\n }\n \n set\n {\n if (value?.GetType() == typeof(bool))\n {\n MultipleBirthBoolean = (bool)value;return;\n }\n \n if (value?.GetType() == typeof(int))\n {\n MultipleBirthInteger = (int)value;return;\n }\n \n throw new ArgumentException(\"Invalid type provided\");\n }\n }\n public object? Deceased \n {\n get\n {\n if (DeceasedDateTime is not null)\n {\n return DeceasedDateTime;\n }\n \n if (DeceasedBoolean is not null)\n {\n return DeceasedBoolean;\n }\n \n return null;\n }\n \n set\n {\n if (value?.GetType() == typeof(string))\n {\n DeceasedDateTime = (string)value;return;\n }\n \n if (value?.GetType() == typeof(bool))\n {\n DeceasedBoolean = (bool)value;return;\n }\n \n throw new ArgumentException(\"Invalid type provided\");\n }\n }\n public Base.Attachment[]? Photo { get; set; }\n public Patient_Link[]? Link { get; set; }\n public bool? Active { get; set; }\n public Patient_Communication[]? Communication { get; set; }\n public Base.Identifier[]? Identifier { get; set; }\n public Base.ContactPoint[]? Telecom { get; set; }\n public Base.ResourceReference[]? GeneralPractitioner { get; set; }\n public string? Gender { get; set; }\n public Base.CodeableConcept? MaritalStatus { get; set; }\n public Patient_Contact[]? Contact { get; set; }\n\n public class Patient_Link : BackboneElement\n {\n public required string Type { get; set; }\n public required Base.ResourceReference Other { get; set; }\n }\n\n public class Patient_Communication : BackboneElement\n {\n public required Base.CodeableConcept Language { get; set; }\n public bool? Preferred { get; set; }\n }\n\n public class Patient_Contact : BackboneElement\n {\n public Base.HumanName? Name { get; set; }\n public string? Gender { get; set; }\n public Base.Period? Period { get; set; }\n public Base.Address? Address { get; set; }\n public Base.ContactPoint[]? Telecom { get; set; }\n public Base.ResourceReference? Organization { get; set; }\n public Base.CodeableConcept[]? Relationship { get; set; }\n }\n}"})))

(deftest test-generate-resource-map
(is
(= ["{ typeof(Aidbox.FHIR.Aidbox.FHIR.R4.Core.Observation), \"Observation\"}"
"{ typeof(Aidbox.FHIR.Aidbox.FHIR.Uv.Sdc.SdcQuestionLibrary), \"SdcQuestionLibrary\"}"]
(gen.dotnet/generate-resource-map [{:package "hl7.fhir.uv.sdc",
:name "Demographics",
:id "sdc-question-library"
:resource-name "sdc-question-library",
:type "Demographics",
:url "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-question-library",
:base "http://hl7.org/fhir/StructureDefinition/Resource",
:fhir-version "hl7.fhir.r4.core"}
{:package "hl7.fhir.r4.core",
:derivation "specialization",
:name "Observation",
:resource-name "Observation",
:type "Observation",
:url "http://hl7.org/fhir/StructureDefinition/Observation",
:base-resource-name "Domain-Resource",
:base "http://hl7.org/fhir/StructureDefinition/DomainResource",
:fhir-version "hl7.fhir.r4.core"}]))))

0 comments on commit fa0582e

Please sign in to comment.