├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches ├── benchmarks.rs ├── large.ttl ├── medium.ttl └── small.ttl ├── build_wasm.sh ├── cog.toml ├── extend_wasm_pkg.sh ├── patch_pkg_json.js ├── prettier.config.js ├── src ├── api │ ├── mod.rs │ ├── ontology.rs │ └── wasm.rs ├── computation │ └── mod.rs ├── error.rs ├── examples │ ├── family.rs │ └── mod.rs ├── lib.rs ├── owl │ ├── axiom.rs │ ├── classes │ │ ├── constructors │ │ │ ├── disjoint_classes.rs │ │ │ ├── equivalent_classes.rs │ │ │ ├── mod.rs │ │ │ ├── object_all_values_from.rs │ │ │ ├── object_complement_of.rs │ │ │ ├── object_exact_cardinality.rs │ │ │ ├── object_has_self.rs │ │ │ ├── object_has_value.rs │ │ │ ├── object_intersection_of.rs │ │ │ ├── object_max_cardinality.rs │ │ │ ├── object_min_cardinality.rs │ │ │ ├── object_one_of.rs │ │ │ ├── object_some_values_from.rs │ │ │ ├── object_union_of.rs │ │ │ └── sub_class_of.rs │ │ └── mod.rs │ ├── datatypes │ │ ├── constructors │ │ │ ├── data_complement_of.rs │ │ │ ├── data_intersection_of.rs │ │ │ ├── data_one_of.rs │ │ │ ├── data_some_values_from.rs │ │ │ ├── data_union_of.rs │ │ │ ├── datatype_definition.rs │ │ │ ├── datatype_restriction.rs │ │ │ └── mod.rs │ │ └── mod.rs │ ├── individual │ │ ├── axioms.rs │ │ └── mod.rs │ ├── iri.rs │ ├── iri_or_list.rs │ ├── lang.rs │ ├── mod.rs │ ├── ontology.rs │ ├── other │ │ ├── has_key.rs │ │ └── mod.rs │ ├── properties │ │ ├── annotation.rs │ │ ├── annotation_property.rs │ │ ├── axioms │ │ │ ├── asymmetric_object_property.rs │ │ │ ├── data_property_domain.rs │ │ │ ├── data_property_range.rs │ │ │ ├── disjoint_object_properties.rs │ │ │ ├── equivalent_data_properties.rs │ │ │ ├── equivalent_object_properties.rs │ │ │ ├── functional_data_property.rs │ │ │ ├── functional_object_property.rs │ │ │ ├── inverse_functional_object_property.rs │ │ │ ├── inverse_object_properties.rs │ │ │ ├── irreflexive_object_property.rs │ │ │ ├── mod.rs │ │ │ ├── object_property_domain.rs │ │ │ ├── object_property_range.rs │ │ │ ├── reflexive_object_property.rs │ │ │ ├── sub_annotation_property_of.rs │ │ │ ├── sub_data_property_of.rs │ │ │ ├── sub_object_property_of.rs │ │ │ ├── symmetric_object_property.rs │ │ │ └── transitive_object_property.rs │ │ ├── constructors │ │ │ ├── mod.rs │ │ │ ├── object_inverse_of.rs │ │ │ └── object_property_chain.rs │ │ ├── mod.rs │ │ └── object_properties.rs │ ├── value.rs │ └── well_known.rs ├── parser │ ├── annotations.rs │ ├── axioms.rs │ ├── blank_nodes.rs │ ├── collector.rs │ ├── data_props.rs │ ├── declarations.rs │ ├── matcher.rs │ ├── mod.rs │ ├── object_property_assertions.rs │ ├── sequences.rs │ └── triple.rs ├── serializer.rs └── utils.rs └── tests ├── apqc.rs ├── apqc.ttl ├── classes.rs ├── classes.ttl ├── data_properties.rs ├── data_properties.ttl ├── expected.ttl ├── large.rs ├── medium.rs ├── object_properties.rs ├── object_properties.ttl ├── reification.rs └── small.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: push 4 | 5 | env: 6 | CARGO_TERM_COLOR: always 7 | jobs: 8 | check: 9 | runs-on: ubuntu-latest 10 | name: Run prechecks 11 | steps: 12 | - uses: actions/checkout@v3 13 | with: 14 | fetch-depth: 0 15 | - name: Conventional commits check 16 | uses: oknozor/cocogitto-action@v2 17 | with: 18 | check-latest-tag-only: true 19 | - name: setup cargo tools 20 | run: | 21 | cargo install cargo-outdated 22 | - name: clippy 23 | run: cargo clippy 24 | - name: outdated and audit 25 | run: | 26 | cargo outdated 27 | cargo audit 28 | 29 | bench: 30 | runs-on: ubuntu-latest 31 | if: github.ref == 'refs/heads/develop' 32 | steps: 33 | - uses: actions/checkout@v3 34 | - name: build 35 | run: SAMPLES=10 cargo bench 36 | 37 | build: 38 | runs-on: ubuntu-latest 39 | needs: check 40 | steps: 41 | - uses: actions/checkout@v3 42 | - name: build 43 | run: cargo build 44 | - name: test 45 | run: cargo test 46 | - name: wasm test 47 | run : | 48 | curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh 49 | ./build_wasm.sh 50 | - name: wasm type checks 51 | run : cd pkg && npm install && npm run tsc 52 | 53 | release: 54 | runs-on: ubuntu-latest 55 | needs: build 56 | if: github.ref == 'refs/heads/main' 57 | steps: 58 | - uses: actions/checkout@v3 59 | with: 60 | fetch-depth: 0 61 | - name: Release crate and npm package 62 | run: | 63 | curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh 64 | echo npm version: 65 | npm --version 66 | cargo install cargo-bump 67 | mkdir -p .cog 68 | wget -O .cog/cocogitto.tar.gz https://github.com/cocogitto/cocogitto/releases/download/5.1.0/cocogitto-5.1.0-x86_64-unknown-linux-musl.tar.gz 69 | tar xvzf .cog/cocogitto.tar.gz --directory .cog/ 70 | git config --global user.email "github@field33.com" 71 | git config --global user.name "github actions" 72 | # 73 | # bump version 74 | .cog/cog bump --auto 75 | rm -rf .cog 76 | TAG_VERSION=$(grep version Cargo.toml | head -1 | sed 's/version = "//g' | sed 's/"//g') 77 | git remote set-url --push origin https://${{ secrets.USERNAME }}:${{ secrets.PAT }}@github.com/field33/owlish 78 | git push 79 | git tag -d v$TAG_VERSION 80 | git tag v$TAG_VERSION 81 | git push origin v$TAG_VERSION 82 | # 83 | # publish crate 84 | cargo publish --token ${{ secrets.CRATES_IO_TOKEN }} 85 | # 86 | # Release npm package 87 | ./build_wasm.sh 88 | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > pkg/.npmrc 89 | cd pkg && npm publish --access public 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 6 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 7 | # Cargo.lock 8 | 9 | # These are backup files generated by rustfmt 10 | **/*.rs.bk 11 | 12 | .cog -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. See [conventional commits](https://www.conventionalcommits.org/) for commit guidelines. 3 | 4 | - - - 5 | ## v0.28.0 - 2023-07-05 6 | #### Features 7 | - **(structure)** Track ResourceIds on assertions for better reification - (6c74c22) - Maximilian Goisser 8 | 9 | - - - 10 | 11 | ## v0.27.0 - 2023-06-27 12 | #### Bug Fixes 13 | - wasm-pack in CI breakage - (eadd2bf) - Maximilian Goisser 14 | #### Features 15 | - Make annotations on OPAs work - (fa9ffd3) - Maximilian Goisser 16 | #### Refactoring 17 | - Rename reification mechanisms that were previously called annotation - (1e0e773) - Maximilian Goisser 18 | 19 | - - - 20 | 21 | ## v0.26.0 - 2023-05-17 22 | #### Features 23 | - **(parsing)** Add support for parsing duration Literals - (3afe3a9) - Maximilian Goisser 24 | 25 | - - - 26 | 27 | ## v0.25.0 - 2023-05-03 28 | #### Features 29 | - Update Typescript dependency to new major version - (40158bd) - Maximilian Goisser 30 | 31 | - - - 32 | 33 | ## v0.24.1 - 2023-04-27 34 | #### Bug Fixes 35 | - Fix broken parsing of annotation assertions with IRI value - (e24da52) - Maximilian Goisser 36 | 37 | - - - 38 | 39 | ## v0.24.0 - 2023-03-24 40 | #### Features 41 | - Expose computations to WASM - (21cdd98) - Maximilian Goisser 42 | 43 | - - - 44 | 45 | ## v0.23.0 - 2023-02-23 46 | #### Documentation 47 | - Add Node.js usage instructions to README - (0834fc6) - Maximilian Goisser 48 | #### Features 49 | - Support field33 computations - (9a912b7) - Florian Loers 50 | 51 | - - - 52 | 53 | ## v0.22.1 - 2023-02-09 54 | #### Bug Fixes 55 | - Annotations on axioms are correctly added to the annotations arrays - (4dc1697) - Florian Loers 56 | 57 | - - - 58 | 59 | ## v0.22.0 - 2023-02-07 60 | #### Features 61 | - Parse annotations on object properties - (50bffcb) - Florian Loers 62 | 63 | - - - 64 | 65 | ## v0.21.2 - 2023-01-31 66 | #### Bug Fixes 67 | - Fix broken parsing of datetime types - (08c7bce) - Florian Loers 68 | 69 | - - - 70 | 71 | ## v0.21.1 - 2023-01-31 72 | #### Bug Fixes 73 | - Add missing date type handling to parser - (e13278a) - Florian Loers 74 | 75 | - - - 76 | 77 | ## v0.21.0 - 2023-01-10 78 | #### Features 79 | - Add parse_triple function to allow parsing single triples - (63cc414) - Florian Loers 80 | 81 | - - - 82 | 83 | ## v0.20.2 - 2023-01-10 84 | #### Bug Fixes 85 | - Parse ClassAssertions based on ClassDeclarations provided in the known array - (99e6350) - Florian Loers 86 | 87 | - - - 88 | 89 | ## v0.20.1 - 2023-01-10 90 | #### Bug Fixes 91 | - Matcher implementations now return values - (983b890) - Florian Loers 92 | 93 | - - - 94 | 95 | ## v0.20.0 - 2023-01-03 96 | #### Features 97 | - Parse reification iris as annotations - (adc3b9b) - Florian Loers 98 | - Add ttl serialization - (775cebf) - Florian Loers 99 | 100 | - - - 101 | 102 | ## v0.19.1 - 2022-12-22 103 | #### Bug Fixes 104 | - Fix error in public type generation - (dd85aed) - Florian Loers 105 | 106 | - - - 107 | 108 | ## v0.19.0 - 2022-12-19 109 | #### Features 110 | - Parse EquivalentOfClasses axioms - (0e99c1d) - Florian Loers 111 | 112 | - - - 113 | 114 | ## v0.18.1 - 2022-12-12 115 | #### Bug Fixes 116 | - Fix parsing UnionOf constructs - (5e75c47) - Florian Loers 117 | 118 | - - - 119 | 120 | ## v0.18.0 - 2022-12-09 121 | #### Features 122 | - Parse Sub*PropertyOf axioms - (2d58473) - Florian Loers 123 | 124 | - - - 125 | 126 | ## v0.17.7 - 2022-11-25 127 | #### Bug Fixes 128 | - Parse unordered sequences - (6b80f43) - Florian Loers 129 | 130 | - - - 131 | 132 | ## v0.17.6 - 2022-11-24 133 | #### Bug Fixes 134 | - Remove print command in parser - (f7fc3d4) - Florian Loers 135 | 136 | - - - 137 | 138 | ## v0.17.5 - 2022-11-23 139 | #### Bug Fixes 140 | - Parse AnnotationProperties that have been defined as DataProperties as well - (ac8b229) - Florian Loers 141 | 142 | - - - 143 | 144 | ## v0.17.4 - 2022-11-22 145 | #### Bug Fixes 146 | - Fix wrong matchDeclaration typescript types - (be08ecd) - Florian Loers 147 | 148 | - - - 149 | 150 | ## v0.17.3 - 2022-11-22 151 | #### Bug Fixes 152 | - Fix wrong Declaration typescript types - (12e6c9a) - Florian Loers 153 | 154 | - - - 155 | 156 | ## v0.17.2 - 2022-11-22 157 | #### Bug Fixes 158 | - Parsing annotations on data properties did not work correctly - (5d50e9d) - Florian Loers 159 | #### Miscellaneous Chores 160 | - Cleanup types - (66541f0) - Florian Loers 161 | 162 | - - - 163 | 164 | ## v0.17.1 - 2022-11-08 165 | #### Bug Fixes 166 | - Parsing annotations on data properties did not work correctly - (012d428) - Florian Loers 167 | 168 | - - - 169 | 170 | ## v0.17.0 - 2022-11-08 171 | #### Features 172 | - Parse annotations on data properties - (f8ed0ad) - Florian Loers 173 | 174 | - - - 175 | 176 | ## v0.16.0 - 2022-11-04 177 | #### Features 178 | - Allow to combine ontologies via Ontology.append - (8ca2ca6) - Florian Loers 179 | 180 | - - - 181 | 182 | ## v0.15.1 - 2022-11-04 183 | #### Bug Fixes 184 | - ClassAssertion has correct class and individual IRIs - (fa44128) - Kate Sieraia 185 | #### Miscellaneous Chores 186 | - Fix tests - (90fa10a) - Kate Sieraia 187 | 188 | - - - 189 | 190 | ## v0.15.0 - 2022-11-01 191 | #### Features 192 | - Support parsing UnionOf constructs in ObjectPropertyDomain and ObjectPropertyRange constructs - (9fded31) - Florian Loers 193 | 194 | - - - 195 | 196 | ## v0.14.0 - 2022-10-20 197 | #### Features 198 | - Support parsing ObjectPropertyRange and ObjectPropertyDomain for simple cases - (ecd1e55) - Florian Loers 199 | 200 | - - - 201 | 202 | ## v0.13.0 - 2022-10-20 203 | #### Features 204 | - Support parsing ObjectProperties - (4f1c8c8) - Florian Loers 205 | 206 | - - - 207 | 208 | ## v0.12.1 - 2022-10-18 209 | #### Bug Fixes 210 | - Fix wrong well_known type export - (4781314) - Florian Loers 211 | 212 | - - - 213 | 214 | ## v0.12.0 - 2022-10-14 215 | #### Features 216 | - Parse unknown Data Property Assertions - (7949d3e) - Kate Sieraia 217 | 218 | - - - 219 | 220 | ## v0.11.1 - 2022-10-13 221 | #### Bug Fixes 222 | - Implement Hash for IRI - (87da92a) - Florian Loers 223 | 224 | - - - 225 | 226 | ## v0.11.0 - 2022-10-07 227 | #### Features 228 | - Parse numeric and bolean literals - (96b710b) - Florian Loers 229 | 230 | - - - 231 | 232 | ## v0.10.0 - 2022-10-06 233 | #### Features 234 | - Parse object property domain and range - (625e5f4) - Florian Loers 235 | 236 | - - - 237 | 238 | ## v0.9.0 - 2022-10-06 239 | #### Features 240 | - Parse annotation assertions with IRIs as values - (5a1bc60) - Florian Loers 241 | 242 | - - - 243 | 244 | ## v0.8.12 - 2022-10-05 245 | #### Bug Fixes 246 | - Adjust types - (9142426) - Florian Loers 247 | 248 | - - - 249 | 250 | ## v0.8.11 - 2022-10-05 251 | #### Bug Fixes 252 | - Improve parser error messages - (cdce6c3) - Florian Loers 253 | 254 | - - - 255 | 256 | ## v0.8.10 - 2022-10-05 257 | #### Bug Fixes 258 | - Improve parser performance - (d9eabce) - Florian Loers 259 | #### Miscellaneous Chores 260 | - Add benchmark tests - (bfe14ed) - Florian Loers 261 | 262 | - - - 263 | 264 | ## v0.8.9 - 2022-09-26 265 | #### Bug Fixes 266 | - Fix wrong typescript IRI type - (3f4feb0) - Florian Loers 267 | 268 | - - - 269 | 270 | ## v0.8.8 - 2022-09-26 271 | #### Bug Fixes 272 | - Fix wrong typescript types and add CI checks for that - (b0f689c) - Florian Loers 273 | 274 | - - - 275 | 276 | ## v0.8.7 - 2022-09-26 277 | #### Bug Fixes 278 | - Fix wrong types in matchDeclaration - (9b18971) - Florian Loers 279 | #### Miscellaneous Chores 280 | - Add keywords and URLs to Cargo.toml - (a7a0fb8) - Maximilian Goisser 281 | - Add badges to README - (4b533fe) - Maximilian Goisser 282 | 283 | - - - 284 | 285 | ## v0.8.6 - 2022-09-19 286 | #### Bug Fixes 287 | - Bump harriet to allow parsing of utf strings - (426fabb) - Florian Loers 288 | 289 | - - - 290 | 291 | ## v0.8.5 - 2022-09-19 292 | #### Bug Fixes 293 | - Parse triples in any order - (433ae93) - Florian Loers 294 | 295 | - - - 296 | 297 | ## v0.8.4 - 2022-09-16 298 | #### Bug Fixes 299 | - Improve parser performance - (00aecbf) - Florian Loers 300 | #### Miscellaneous Chores 301 | - Improve logging and add more tests - (982b9a3) - Florian Loers 302 | 303 | - - - 304 | 305 | ## v0.8.3 - 2022-09-14 306 | #### Bug Fixes 307 | - RDF Parser ignores order of triples - (ae037d6) - Florian Loers 308 | 309 | - - - 310 | 311 | ## v0.8.2 - 2022-09-14 312 | #### Bug Fixes 313 | - Patch package.json in release action - (c283249) - Maximilian Goisser 314 | 315 | - - - 316 | 317 | ## v0.8.1 - 2022-09-14 318 | #### Bug Fixes 319 | - Improve owlish parser performance - (f5e8467) - Florian Loers 320 | 321 | - - - 322 | 323 | ## v0.8.0 - 2022-09-13 324 | #### Features 325 | - Improve owlish parser for computation logic - (47b73b3) - Florian Loers 326 | 327 | - - - 328 | 329 | ## v0.7.0 - 2022-09-08 330 | #### Features 331 | - Add spec-based rdf triple parser - (dd00a40) - Florian Loers 332 | 333 | - - - 334 | 335 | ## v0.6.2 - 2022-09-01 336 | #### Bug Fixes 337 | - Improve typescript types - (8c52359) - Florian Loers 338 | #### Miscellaneous Chores 339 | - Remove wee alloc - (e10a230) - Florian Loers 340 | 341 | - - - 342 | 343 | ## v0.6.1 - 2022-08-17 344 | #### Bug Fixes 345 | - Fix broken wasm API for Iri handling - (cf6f89d) - Florian Loers 346 | 347 | - - - 348 | 349 | ## v0.6.0 - 2022-08-17 350 | #### Features 351 | - Provide Iri constructor with validation - (2292248) - Florian Loers 352 | - Allow annotations for Declarations - (011697c) - Florian Loers 353 | 354 | - - - 355 | 356 | ## v0.5.0 - 2022-08-12 357 | #### Features 358 | - Support annotations in ObjectProperty, DataProperty and AnnotationProperty - (e3d84c3) - Florian Loers 359 | 360 | - - - 361 | 362 | ## v0.4.3 - 2022-08-08 363 | #### Bug Fixes 364 | - Support json deserialization and mutation API - (789c874) - Florian Loers 365 | #### Miscellaneous Chores 366 | - Bump harriet version - (79c06b1) - Florian Loers 367 | - Improve parser - (67e5a6d) - Florian Loers 368 | 369 | - - - 370 | 371 | ## v0.4.2 - 2022-07-18 372 | #### Bug Fixes 373 | - **(parser)** Ignore blank nodes instead of failing - (30ca15b) - Florian Loers 374 | 375 | - - - 376 | 377 | ## v0.4.1 - 2022-07-18 378 | #### Bug Fixes 379 | - Allow conditional wasm compilation - (6d4c7ec) - Florian Loers 380 | #### Continuous Integration 381 | - Reintroduce precheck and test steps - (84977f6) - Florian Loers 382 | 383 | - - - 384 | 385 | ## v0.4.0 - 2022-07-17 386 | #### Features 387 | - Add proper WASM bindings - (9903344) - Florian Loers 388 | 389 | - - - 390 | 391 | ## v0.2.0 - 2022-07-12 392 | #### Continuous Integration 393 | - Fix release job versioning - (49a8f48) - Florian Loers 394 | #### Features 395 | - Add wasm capabilities - (9cdfe65) - Florian Loers 396 | - Add turtle parsing with harriet and wasm API - (f462b16) - Florian Loers 397 | #### Miscellaneous Chores 398 | - Rename to owlish - (edbea35) - Florian Loers 399 | 400 | - - - 401 | 402 | ## v0.1.0 - 2022-05-11 403 | #### Features 404 | - Improve owlib convinience and documentation - (f038876) - Florian Loers 405 | 406 | - - - 407 | 408 | ## v0.0.1 - 2022-05-11 409 | #### Miscellaneous Chores 410 | - Setup initial draft version of owl library - (8e105f4) - Florian Loers 411 | - - - 412 | 413 | Changelog generated by [cocogitto](https://github.com/cocogitto/cocogitto). -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "owlish" 3 | version = "0.28.0" 4 | edition = "2021" 5 | description = "OWL 2 implementation with wasm support and turtle parsing" 6 | authors = ["Field33", "Florian Loers "] 7 | readme = "README.md" 8 | license = "MIT OR Apache-2.0" 9 | repository = "https://github.com/field33/owlish" 10 | documentation = "https://docs.rs/owlish" 11 | keywords = ["owl", "rdf", "semantic-web"] 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [features] 17 | default = ["console_error_panic_hook"] 18 | wasm = ["wasm-bindgen"] 19 | 20 | [dependencies] 21 | iref = "2" 22 | serde = { version = "1", features = ["derive"] } 23 | serde_json = "1" 24 | wasm-bindgen = { version = "0.2", features = [ 25 | "serde-serialize", 26 | ], optional = true } 27 | js-sys = "0.3" 28 | web-sys = { version = "0.3", features = ["console"] } 29 | # harriet = { git = "https://github.com/field33/harriet" } 30 | harriet = "0.3.1" 31 | # Toggle on the serde support of harriets dependency 32 | snowflake = { version = "1.3.0", features = ["serde_support"] } 33 | oxsdatatypes = "0.1.1" 34 | time = { version = "0.3", features = ["formatting"] } 35 | # The `console_error_panic_hook` crate provides better debugging of panics by 36 | # logging them with `console.error`. This is great for development, but requires 37 | # all the `std::fmt` and `std::panicking` infrastructure, so isn't great for 38 | # code size when deploying. 39 | console_error_panic_hook = { version = "0.1", optional = true } 40 | 41 | pct-str = "1.1.0" 42 | log = "0.4" 43 | env_logger = "0.10" 44 | serde-wasm-bindgen = "0.4.3" 45 | 46 | [dev-dependencies] 47 | wasm-bindgen-test = "0.3.32" 48 | criterion = "0.4" 49 | 50 | [[bench]] 51 | name = "benchmarks" 52 | harness = false 53 | 54 | [profile.release] 55 | # Tell `rustc` to optimize for small code size. 56 | opt-level = "s" 57 | 58 | [profile.bench] 59 | debug = true 60 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT LICENSE 2 | 3 | Copyright (c) 2021 The harriet Project Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # owlish 2 | 3 | [github](https://github.com/field33/owlish) 4 | [crates.io](https://crates.io/crates/owlish) 5 | [docs.rs](https://docs.rs/owlish) 6 | [npmjs.com](https://www.npmjs.com/package/owlish) 7 | 8 | This library provides OWL2 datastructures that allow you to build and work with ontologies. 9 | 10 | The OWL2 model is based on functional style syntax. E.g. the function 11 | 12 | ``` 13 | ClassAssertion( :Person :Mary ) 14 | ``` 15 | 16 | Is represented as a similar tuple struct 17 | 18 | ```rust 19 | pub struct ClassAssertion(pub(crate) ClassConstructor, pub(crate) IndividualIRI); 20 | ``` 21 | 22 | ## Usage 23 | 24 | owlish provides two APIs: 25 | 26 | 1. A low level representation of OWL based on functional syntax 27 | - This is exported in `owlish::owl::*` 28 | 2. A conceptional api that concatenates OWL data for relevant types. 29 | - TBD 30 | 31 | ## Usage (Node.js) 32 | 33 | To initialize the module in a Node.js environment, it is currently recommend to load the WASM module via the `fs` API and 34 | pass it explicitly to the initialization function. 35 | 36 | Example: 37 | ```js 38 | import path from 'path'; 39 | import { readFile } from 'fs/promises'; 40 | import { fileURLToPath } from 'url'; 41 | 42 | // The next two lines are only required if running the Node script as an ESM module 43 | const __filename = fileURLToPath(import.meta.url); 44 | const __dirname = path.dirname(__filename); 45 | // Load .wasm file from the package 46 | const owlishWasm = await readFile(path.join(__dirname, "../node_modules/owlish/owlish_bg.wasm")); 47 | // Initialize module, after executing this line, all functions from `owlish` can be used like normal. 48 | await owlish(owlishWasm) 49 | ``` 50 | 51 | ## Dev stuff 52 | 53 | Build: 54 | 55 | ``` 56 | cargo build 57 | ``` 58 | 59 | Test: 60 | 61 | ``` 62 | cargo test 63 | ``` 64 | 65 | Run benchmark tests: 66 | 67 | ``` 68 | cargo bench 69 | ``` 70 | 71 | ## Commits and Releases 72 | 73 | This crate uses [convenentional commits](https://www.conventionalcommits.org/en/v1.0.0/) to create automated releases whenever the main branch is updated. In addition the CHANGELOG.md is automatically generated. 74 | -------------------------------------------------------------------------------- /benches/benchmarks.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Bencher, Criterion}; 2 | use owlish::{api::Ontology, owl::IRI, parser::ParserOptions}; 3 | 4 | fn parser_benchmarks(c: &mut Criterion) { 5 | env_logger::try_init().ok(); 6 | c.bench_function("35000 individuals, 14000 axioms", |b| { 7 | parser_bench(b, include_str!("./large.ttl")) 8 | }); 9 | c.bench_function("2000 individuals, 800 axioms", |b| { 10 | parser_bench(b, include_str!("./medium.ttl")) 11 | }); 12 | c.bench_function("1000 individuals, 0 aximos", |b| { 13 | parser_bench(b, include_str!("./small.ttl")) 14 | }); 15 | } 16 | 17 | criterion_group! { 18 | name = parser; 19 | config = Criterion::default().significance_level(0.2).sample_size(std::env::var("SAMPLES").ok().and_then(|s| s.parse::().ok()).unwrap_or(10)); 20 | targets = parser_benchmarks 21 | } 22 | criterion_main!(parser); 23 | 24 | pub fn parser_bench(b: &mut Bencher, turtle: &str) { 25 | harriet::TurtleDocument::parse_full(turtle) 26 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 27 | .expect("Could not parse with harriet"); 28 | b.iter(|| { 29 | Ontology::parse( 30 | turtle, 31 | ParserOptions::builder() 32 | .known(owlish::owl::Declaration::AnnotationProperty { 33 | iri: IRI::new("http://query-server.field33.com/ontology/query-field") 34 | .unwrap() 35 | .into(), 36 | annotations: vec![], 37 | }) 38 | .build(), 39 | ) 40 | .unwrap(); 41 | }) 42 | } 43 | -------------------------------------------------------------------------------- /build_wasm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | wasm-pack build --target web --release --features wasm,console_error_panic_hook && ./extend_wasm_pkg.sh && node patch_pkg_json.js -------------------------------------------------------------------------------- /cog.toml: -------------------------------------------------------------------------------- 1 | tag_prefix = "v" 2 | 3 | pre_bump_hooks = [ 4 | "cargo bump {{version}}", 5 | "cargo update", 6 | ] 7 | post_bump_hooks = [ 8 | "git add Cargo.toml", 9 | "git commit --amend --no-edit" 10 | ] 11 | 12 | [commit_types] 13 | 14 | [changelog] 15 | path = "CHANGELOG.md" 16 | authors = [] 17 | 18 | [bump_profiles] 19 | -------------------------------------------------------------------------------- /extend_wasm_pkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | API=" 3 | // CUSTOM API FROM extend_wasm_pkg.sh 4 | // ------------------------------------------------------ 5 | 6 | export function matchValue(value, matcher) { 7 | if ( 8 | matcher.string && 9 | matcher.boolean && 10 | matcher.dateTime && 11 | matcher.number && 12 | matcher.duration && 13 | matcher.raw 14 | ) { 15 | switch (value._type) { 16 | case 'string': 17 | case 'langString': 18 | return matcher.string(value) 19 | case 'raw': 20 | return matcher.raw(value) 21 | case 'dateTime': 22 | return matcher.dateTime(value) 23 | case 'number': 24 | return matcher.number(value) 25 | case 'boolean': 26 | return matcher.boolean(value) 27 | case 'duration': 28 | return matcher.duration(value) 29 | } 30 | } else if (matcher.default) { 31 | switch (value._type) { 32 | case 'string': 33 | case 'langString': 34 | return matcher.string !== undefined 35 | ? matcher.string(value) 36 | : matcher.default(value) 37 | case 'raw': 38 | return matcher.raw !== undefined 39 | ? matcher.raw(value) 40 | : matcher.default(value) 41 | case 'dateTime': 42 | return matcher.dateTime !== undefined 43 | ? matcher.dateTime(value) 44 | : matcher.default(value) 45 | case 'number': 46 | return matcher.number !== undefined 47 | ? matcher.number(value) 48 | : matcher.default(value) 49 | case 'boolean': 50 | return matcher.boolean !== undefined 51 | ? matcher.boolean(value) 52 | : matcher.default(value) 53 | case 'duration': 54 | return matcher.duration !== undefined 55 | ? matcher.duration(value) 56 | : matcher.default(value) 57 | default: 58 | return matcher.default(value) 59 | } 60 | } else { 61 | throw new Error('Non exhaustive value match!') 62 | } 63 | } 64 | 65 | 66 | export function matchAxiom(axiom, matcher) { 67 | for (const key in axiom) { 68 | if (matcher[key]) { 69 | return matcher[key](axiom[key]) 70 | break 71 | } 72 | } 73 | } 74 | 75 | export function matchDeclaration(declaration, matcher) { 76 | for (const key in declaration) { 77 | if (matcher[key]) { 78 | return matcher[key](declaration[key]) 79 | break 80 | } 81 | } 82 | } 83 | 84 | export function matchClassConst(axiom, matcher) { 85 | for (const key in axiom) { 86 | if (matcher[key]) { 87 | return matcher[key](axiom[key]) 88 | break 89 | } 90 | } 91 | } 92 | export class IRI { 93 | _type 94 | string 95 | } 96 | " 97 | echo "$API" >> ./pkg/owlish.js 98 | -------------------------------------------------------------------------------- /patch_pkg_json.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') // replace with import fs from 'fs'; if you need 2 | const packageFileContent = fs.readFileSync('./pkg/package.json', 'utf-8') 3 | const packageJSON = JSON.parse(packageFileContent) 4 | packageJSON.type = 'module' 5 | packageJSON.main = packageJSON.module 6 | packageJSON.exports = './' + packageJSON.module 7 | packageJSON.dependencies = { typescript: '^5.0.0' } 8 | packageJSON.scripts = { tsc: 'tsc owlish.d.ts' } 9 | fs.writeFileSync( 10 | './pkg/package.json', 11 | JSON.stringify(packageJSON, null, 2), 12 | 'utf-8' 13 | ) 14 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | trailingComma: 'es5', 3 | tabWidth: 4, 4 | semi: false, 5 | singleQuote: true, 6 | } 7 | -------------------------------------------------------------------------------- /src/api/mod.rs: -------------------------------------------------------------------------------- 1 | mod ontology; 2 | pub use ontology::*; 3 | 4 | pub use crate::owl::IRI; 5 | pub use crate::owl::Axiom; 6 | 7 | #[cfg(feature = "wasm")] // TODO 8 | pub mod wasm; 9 | -------------------------------------------------------------------------------- /src/api/ontology.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | use std::collections::HashMap; 3 | 4 | use crate::owl::{AnnotationAssertion, Axiom, Declaration, IRIBuilder, ResourceId, IRI}; 5 | 6 | #[cfg(feature = "wasm")] 7 | #[wasm_bindgen::prelude::wasm_bindgen] 8 | #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] 9 | pub struct Ontology { 10 | pub(crate) iri: IRI, 11 | pub(crate) imports: HashMap, 12 | pub(crate) owl: crate::owl::Ontology, 13 | } 14 | 15 | #[cfg(not(feature = "wasm"))] 16 | #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] 17 | pub struct Ontology { 18 | pub(crate) iri: IRI, 19 | pub(crate) imports: HashMap, 20 | pub(crate) owl: crate::owl::Ontology, 21 | } 22 | 23 | impl Ontology { 24 | /// Creates a new Ontology 25 | pub fn new(iri: IRI) -> Self { 26 | Self { 27 | iri, 28 | imports: Default::default(), 29 | owl: crate::owl::Ontology::new(vec![], vec![]), 30 | } 31 | } 32 | 33 | pub fn iri(&self) -> &IRI { 34 | &self.iri 35 | } 36 | 37 | /// Get the map of all imports 38 | pub fn imports(&self) -> &HashMap { 39 | &self.imports 40 | } 41 | 42 | /// push the given iri with name as import. 43 | /// If an import for this name already existed the old iri is returned. 44 | pub fn push_import(&mut self, name: &str, iri: IRI) -> Option { 45 | self.imports.insert(name.into(), iri) 46 | } 47 | 48 | /// Get a IRIBuilder to create new iris based on imports for this ontology. 49 | pub fn iri_builder(&self) -> IRIBuilder { 50 | IRIBuilder::construct(self.iri.clone(), &self.imports) 51 | } 52 | 53 | /// Get all OWL declarations of this ontology. 54 | pub fn declarations(&self) -> &Vec { 55 | &self.owl.declarations 56 | } 57 | 58 | /// Get all OWL axioms of this ontology. 59 | pub fn axioms(&self) -> &Vec { 60 | &self.owl.axioms 61 | } 62 | 63 | /// Finds all annotations assertions for a given `ResourceId`. 64 | pub fn annotation_assertions_for_resource_id( 65 | &self, 66 | resource_id: &ResourceId, 67 | ) -> Vec { 68 | let mut annotations = vec![]; 69 | // Add annotations that are on the axiom directly 70 | for axiom in self.axioms() { 71 | if let Some(axiom_annotations) = match axiom { 72 | Axiom::AnnotationAssertion(apa) => { 73 | if apa.resource_ids.contains(resource_id) { 74 | Some(apa.annotations.clone()) 75 | } else { 76 | None 77 | } 78 | } 79 | Axiom::DataPropertyAssertion(dpa) => { 80 | if dpa.resource_ids.contains(resource_id) { 81 | Some(dpa.annotations.clone()) 82 | } else { 83 | None 84 | } 85 | } 86 | Axiom::ObjectPropertyAssertion(opa) => { 87 | if opa.resource_ids.contains(resource_id) { 88 | Some(opa.annotations.clone()) 89 | } else { 90 | None 91 | } 92 | } 93 | _ => { 94 | None 95 | // unimplemented!("`annotationsForResourceId` is only implemented for assertions right now") 96 | } 97 | } { 98 | for annotation in &axiom_annotations { 99 | annotations.push(annotation.clone().to_assertion(resource_id.to_owned())); 100 | } 101 | } 102 | } 103 | // Find additional AnnotationAssertions via matching their subject to resource_id 104 | for axiom in self.axioms() { 105 | if let Axiom::AnnotationAssertion(annotation_assertion) = axiom { 106 | if &annotation_assertion.subject == resource_id { 107 | annotations.push(annotation_assertion.clone()); 108 | } 109 | } 110 | } 111 | 112 | // HACK: This may not remove all duplicates, as we can't order the Vec before deduping. 113 | annotations.dedup(); 114 | annotations 115 | } 116 | } 117 | 118 | /// mutation api 119 | impl Ontology { 120 | /// Set the owl data 121 | pub fn set_owl(&mut self, owl: crate::owl::Ontology) { 122 | self.owl = owl 123 | } 124 | 125 | /// Push the given OWL axiom to this ontology 126 | pub fn push_axiom(&mut self, axiom: Axiom) { 127 | self.owl.axioms.push(axiom) 128 | } 129 | 130 | /// Push the given OWL declaration to this ontology 131 | pub fn push_declaration(&mut self, declaration: Declaration) { 132 | self.owl.declarations.push(declaration) 133 | } 134 | } 135 | 136 | impl From<(IRI, crate::owl::Ontology)> for Ontology { 137 | fn from((iri, owl): (IRI, crate::owl::Ontology)) -> Self { 138 | Self { 139 | iri, 140 | imports: Default::default(), 141 | owl, 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/computation/mod.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use crate::{ 5 | api::{Ontology, IRI}, 6 | owl::{well_known, Axiom, ClassAssertion, ClassConstructor}, 7 | }; 8 | 9 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] 10 | pub struct Computation { 11 | iri: IRI, 12 | axioms: Vec, 13 | } 14 | 15 | impl Computation { 16 | pub fn iri(&self) -> &IRI { 17 | &self.iri 18 | } 19 | pub fn axioms(&self) -> &Vec { 20 | &self.axioms 21 | } 22 | } 23 | 24 | pub trait GetComputations { 25 | fn computations(&self) -> Vec; 26 | } 27 | 28 | impl GetComputations for Ontology { 29 | fn computations(&self) -> Vec { 30 | let mut computations: HashMap = HashMap::new(); 31 | 32 | for axiom in self.owl.axioms() { 33 | if let Axiom::ClassAssertion(ClassAssertion { 34 | cls, 35 | individual, 36 | annotations: _, 37 | }) = axiom 38 | { 39 | let individual = individual.as_iri(); 40 | if let ClassConstructor::IRI(iri) = cls { 41 | let iri = iri.as_iri(); 42 | if iri == &well_known::fno_Function() { 43 | computations.insert( 44 | individual.clone(), 45 | Computation { 46 | iri: individual.clone(), 47 | axioms: Vec::new(), 48 | }, 49 | ); 50 | } 51 | } 52 | } 53 | } 54 | 55 | for axiom in self.owl.axioms() { 56 | if let Some(subject) = axiom.subject() { 57 | if let Some(comp) = computations.get_mut(subject) { 58 | comp.axioms.push(axiom.clone()); 59 | } 60 | } 61 | } 62 | computations.into_values().collect() 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | 3 | #[derive(Debug)] 4 | pub struct Error { 5 | message: String, 6 | } 7 | 8 | impl std::error::Error for Error { 9 | fn description(&self) -> &str { 10 | &self.message 11 | } 12 | } 13 | 14 | impl Display for Error { 15 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 16 | write!(f, "{}", self.message) 17 | } 18 | } 19 | 20 | impl Error { 21 | pub fn new(message: String) -> Self { 22 | Self { message } 23 | } 24 | } 25 | 26 | impl From for Error { 27 | fn from(e: iref::Error) -> Self { 28 | Error { 29 | message: e.to_string(), 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/examples/mod.rs: -------------------------------------------------------------------------------- 1 | mod family; 2 | pub use family::*; 3 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Rust and WASM OWL Library 2 | //! 3 | //! # Examples 4 | //! 5 | //! ```rust 6 | //! use owlish::api::*; 7 | //! 8 | //! 9 | //! 10 | //! ``` 11 | 12 | extern crate log; 13 | 14 | pub mod api; 15 | pub mod error; 16 | pub mod owl; 17 | 18 | pub mod examples; 19 | pub mod parser; 20 | pub mod serializer; 21 | 22 | pub mod computation; -------------------------------------------------------------------------------- /src/owl/axiom.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use crate::owl::*; 4 | 5 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] 6 | pub enum Axiom { 7 | // Annotations 8 | AnnotationAssertion(AnnotationAssertion), 9 | AnnotationPropertyRange(AnnotationPropertyRange), 10 | AnnotationPropertyDomain(AnnotationPropertyDomain), 11 | // Properties 12 | SubObjectPropertyOf(SubObjectPropertyOf), 13 | SubDataPropertyOf(SubDataPropertyOf), 14 | SubAnnotationPropertyOf(SubAnnotationPropertyOf), 15 | EquivalentObjectProperties(EquivalentObjectProperties), 16 | EquivalentDataProperties(EquivalentDataProperties), 17 | InverseObjectProperties(InverseObjectProperties), 18 | DisjointObjectProperties(DisjointObjectProperties), 19 | ObjectPropertyDomain(ObjectPropertyDomain), 20 | ObjectPropertyRange(ObjectPropertyRange), 21 | DataPropertyDomain(DataPropertyDomain), 22 | DataPropertyRange(DataPropertyRange), 23 | SymmetricObjectProperty(SymmetricObjectProperty), 24 | AsymmetricObjectProperty(AsymmetricObjectProperty), 25 | ReflexiveObjectProperty(ReflexiveObjectProperty), 26 | IrreflexiveObjectProperty(IrreflexiveObjectProperty), 27 | FunctionalObjectProperty(FunctionalObjectProperty), 28 | InverseFunctionalObjectProperty(InverseFunctionalObjectProperty), 29 | TransitiveObjectProperty(TransitiveObjectProperty), 30 | FunctionalDataProperty(FunctionalDataProperty), 31 | // Classes 32 | SubClassOf(SubClassOf), 33 | EquivalentClasses(EquivalentClasses), 34 | DisjointClasses(DisjointClasses), 35 | // Datatypes 36 | DatatypeDefinition(DatatypeDefinition), 37 | // Individuals 38 | ClassAssertion(ClassAssertion), 39 | SameIndividual(SameIndividual), 40 | DifferentIndividuals(DifferentIndividuals), 41 | // ObjectProperties 42 | ObjectPropertyAssertion(ObjectPropertyAssertion), 43 | NegativeObjectPropertyAssertion(NegativeObjectPropertyAssertion), 44 | // DataProperties 45 | DataPropertyAssertion(DataPropertyAssertion), 46 | NegativeDataPropertyAssertion(NegativeDataPropertyAssertion), 47 | // Other 48 | HasKey(HasKey), 49 | } 50 | 51 | impl Axiom { 52 | pub fn annotations_mut(&mut self) -> &mut Vec { 53 | match self { 54 | Axiom::AnnotationAssertion(a) => &mut a.annotations, 55 | Axiom::AnnotationPropertyDomain(a) => &mut a.annotations, 56 | Axiom::AnnotationPropertyRange(a) => &mut a.annotations, 57 | Axiom::SubObjectPropertyOf(a) => &mut a.annotations, 58 | Axiom::SubAnnotationPropertyOf(a) => &mut a.annotations, 59 | Axiom::SubDataPropertyOf(a) => &mut a.annotations, 60 | Axiom::EquivalentObjectProperties(a) => &mut a.annotations, 61 | Axiom::EquivalentDataProperties(a) => &mut a.annotations, 62 | Axiom::InverseObjectProperties(a) => &mut a.annotations, 63 | Axiom::DisjointObjectProperties(a) => &mut a.annotations, 64 | Axiom::ObjectPropertyDomain(a) => &mut a.annotations, 65 | Axiom::ObjectPropertyRange(a) => &mut a.annotations, 66 | Axiom::DataPropertyDomain(a) => &mut a.annotations, 67 | Axiom::DataPropertyRange(a) => &mut a.annotations, 68 | Axiom::SymmetricObjectProperty(a) => &mut a.annotations, 69 | Axiom::AsymmetricObjectProperty(a) => &mut a.annotations, 70 | Axiom::ReflexiveObjectProperty(a) => &mut a.annotations, 71 | Axiom::IrreflexiveObjectProperty(a) => &mut a.annotations, 72 | Axiom::FunctionalObjectProperty(a) => &mut a.annotations, 73 | Axiom::InverseFunctionalObjectProperty(a) => &mut a.annotations, 74 | Axiom::TransitiveObjectProperty(a) => &mut a.annotations, 75 | Axiom::FunctionalDataProperty(a) => &mut a.annotations, 76 | Axiom::SubClassOf(a) => &mut a.annotations, 77 | Axiom::EquivalentClasses(a) => &mut a.annotations, 78 | Axiom::DisjointClasses(a) => &mut a.annotations, 79 | Axiom::DatatypeDefinition(a) => &mut a.annotations, 80 | Axiom::ClassAssertion(a) => &mut a.annotations, 81 | Axiom::SameIndividual(a) => &mut a.annotations, 82 | Axiom::DifferentIndividuals(a) => &mut a.annotations, 83 | Axiom::ObjectPropertyAssertion(a) => &mut a.annotations, 84 | Axiom::NegativeObjectPropertyAssertion(a) => &mut a.annotations, 85 | Axiom::DataPropertyAssertion(a) => &mut a.annotations, 86 | Axiom::NegativeDataPropertyAssertion(a) => &mut a.annotations, 87 | Axiom::HasKey(a) => &mut a.annotations, 88 | } 89 | } 90 | 91 | pub fn subject(&self) -> Option<&IRI> { 92 | match self { 93 | Axiom::AnnotationAssertion(a) => { 94 | // TODO: This seems like it could be a source for confusion (silently not having a subject if it's a BlankNode 95 | match &a.subject { 96 | ResourceId::IRI(iri_subject) => { 97 | Some(&iri_subject) 98 | } 99 | ResourceId::BlankNode(_) => {None} 100 | } 101 | }, 102 | Axiom::AnnotationPropertyRange(a) => Some(a.iri.as_iri()), 103 | Axiom::AnnotationPropertyDomain(a) => Some(a.iri.as_iri()), 104 | Axiom::SubObjectPropertyOf(a) => match &a.object_property { 105 | ObjectPropertyConstructor::IRI(iri) => Some(iri.as_iri()), 106 | ObjectPropertyConstructor::ObjectInverseOf(_) => None, 107 | ObjectPropertyConstructor::ObjectPropertyChain(_) => None, 108 | }, 109 | Axiom::SubDataPropertyOf(a) => Some(a.subject_iri.as_iri()), 110 | Axiom::SubAnnotationPropertyOf(a) => Some(a.subject_iri.as_iri()), 111 | Axiom::EquivalentObjectProperties(a) => Some(a.object_property_iri_1.as_iri()), 112 | Axiom::EquivalentDataProperties(a) => Some(a.data_property_iri_1.as_iri()), 113 | Axiom::InverseObjectProperties(a) => Some(a.object_property_iri_1.as_iri()), 114 | Axiom::DisjointObjectProperties(a) => Some(a.object_property_iri_1.as_iri()), 115 | Axiom::ObjectPropertyDomain(a) => Some(a.iri.as_iri()), 116 | Axiom::ObjectPropertyRange(a) => Some(a.iri.as_iri()), 117 | Axiom::DataPropertyDomain(a) => Some(a.iri.as_iri()), 118 | Axiom::DataPropertyRange(a) => Some(a.iri.as_iri()), 119 | Axiom::SymmetricObjectProperty(a) => Some(a.object_property_iri.as_iri()), 120 | Axiom::AsymmetricObjectProperty(a) => Some(a.object_property_iri.as_iri()), 121 | Axiom::ReflexiveObjectProperty(a) => Some(a.object_property_iri.as_iri()), 122 | Axiom::IrreflexiveObjectProperty(a) => Some(a.object_property_iri.as_iri()), 123 | Axiom::FunctionalObjectProperty(a) => Some(a.object_property_iri.as_iri()), 124 | Axiom::InverseFunctionalObjectProperty(a) => Some(a.object_property_iri.as_iri()), 125 | Axiom::TransitiveObjectProperty(a) => Some(a.object_property_iri.as_iri()), 126 | Axiom::FunctionalDataProperty(a) => Some(a.data_property_iri.as_iri()), 127 | Axiom::SubClassOf(a) => match a.cls.as_ref() { 128 | ClassConstructor::IRI(iri) => Some(iri.as_iri()), 129 | _ => None, 130 | }, 131 | Axiom::EquivalentClasses(a) => Some(a.class_iri.as_iri()), 132 | Axiom::DisjointClasses(_) => None, 133 | Axiom::DatatypeDefinition(a) => Some(a.data_property_iri.as_iri()), 134 | Axiom::ClassAssertion(a) => Some(a.individual.as_iri()), 135 | Axiom::SameIndividual(a) => Some(a.individual1.as_iri()), 136 | Axiom::DifferentIndividuals(a) => Some(a.individual1.as_iri()), 137 | Axiom::ObjectPropertyAssertion(a) => Some(a.subject.as_iri()), 138 | Axiom::NegativeObjectPropertyAssertion(a) => Some(a.subject.as_iri()), 139 | Axiom::DataPropertyAssertion(a) => Some(a.subject.as_iri()), 140 | Axiom::NegativeDataPropertyAssertion(a) => Some(a.subject.as_iri()), 141 | Axiom::HasKey(a) => Some(a.iri.as_iri()), 142 | } 143 | } 144 | } 145 | 146 | impl From for Axiom { 147 | fn from(s: SubObjectPropertyOf) -> Self { 148 | Self::SubObjectPropertyOf(s) 149 | } 150 | } 151 | 152 | impl From for Axiom { 153 | fn from(s: SubAnnotationPropertyOf) -> Self { 154 | Self::SubAnnotationPropertyOf(s) 155 | } 156 | } 157 | 158 | impl From for Axiom { 159 | fn from(s: SubDataPropertyOf) -> Self { 160 | Self::SubDataPropertyOf(s) 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/disjoint_classes.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct DisjointClasses { 5 | pub classes: Vec, 6 | pub annotations: Vec, 7 | } 8 | 9 | impl DisjointClasses { 10 | pub fn new(classes: Vec, annotations: Vec) -> Self { 11 | Self { 12 | classes, 13 | annotations, 14 | } 15 | } 16 | } 17 | 18 | impl From for ClassConstructor { 19 | fn from(c: DisjointClasses) -> Self { 20 | ClassConstructor::DisjointClasses(c) 21 | } 22 | } 23 | impl From for Box { 24 | fn from(c: DisjointClasses) -> Self { 25 | Box::new(ClassConstructor::DisjointClasses(c)) 26 | } 27 | } 28 | 29 | impl ClassConstructor { 30 | pub fn disjoint_classes(&self) -> Option<&DisjointClasses> { 31 | match self { 32 | ClassConstructor::DisjointClasses(d) => Some(d), 33 | _ => None, 34 | } 35 | } 36 | } 37 | 38 | #[cfg(feature = "wasm")] 39 | mod wasm { 40 | use wasm_bindgen::prelude::wasm_bindgen; 41 | 42 | #[wasm_bindgen(typescript_custom_section)] 43 | const WASM_API: &'static str = r#" 44 | export type DisjointClasses = { 45 | classes: Array, 46 | annotations: Array, 47 | }; 48 | "#; 49 | } 50 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/equivalent_classes.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor, ClassIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct EquivalentClasses { 5 | #[serde(rename = "classIRI")] 6 | pub class_iri: ClassIRI, 7 | pub cls: Box, 8 | pub annotations: Vec, 9 | } 10 | 11 | impl EquivalentClasses { 12 | pub fn new( 13 | class_iri: ClassIRI, 14 | cls: Box, 15 | annotations: Vec, 16 | ) -> Self { 17 | Self { 18 | class_iri, 19 | cls, 20 | annotations, 21 | } 22 | } 23 | } 24 | 25 | impl From for Box { 26 | fn from(c: EquivalentClasses) -> Self { 27 | Box::new(ClassConstructor::EquivalentClasses(c)) 28 | } 29 | } 30 | impl From for ClassConstructor { 31 | fn from(c: EquivalentClasses) -> Self { 32 | ClassConstructor::EquivalentClasses(c) 33 | } 34 | } 35 | 36 | impl ClassConstructor { 37 | pub fn equivalent_classes(&self) -> Option<&EquivalentClasses> { 38 | match self { 39 | ClassConstructor::EquivalentClasses(d) => Some(d), 40 | _ => None, 41 | } 42 | } 43 | } 44 | 45 | #[cfg(feature = "wasm")] 46 | mod wasm { 47 | use wasm_bindgen::prelude::wasm_bindgen; 48 | 49 | #[wasm_bindgen(typescript_custom_section)] 50 | const WASM_API: &'static str = r#" 51 | export type EquivalentClasses = { 52 | classIRI: IRI, 53 | cls: ClassConstructor, 54 | annotations: Array, 55 | }; 56 | "#; 57 | } 58 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/mod.rs: -------------------------------------------------------------------------------- 1 | mod sub_class_of; 2 | 3 | pub use sub_class_of::*; 4 | 5 | mod equivalent_classes; 6 | pub use equivalent_classes::*; 7 | 8 | mod disjoint_classes; 9 | pub use disjoint_classes::*; 10 | 11 | mod object_intersection_of; 12 | pub use object_intersection_of::*; 13 | 14 | mod object_union_of; 15 | pub use object_union_of::*; 16 | 17 | mod object_complement_of; 18 | pub use object_complement_of::*; 19 | 20 | mod object_some_values_from; 21 | pub use object_some_values_from::*; 22 | 23 | mod object_max_cardinality; 24 | pub use object_max_cardinality::*; 25 | 26 | mod object_min_cardinality; 27 | pub use object_min_cardinality::*; 28 | 29 | mod object_exact_cardinality; 30 | pub use object_exact_cardinality::*; 31 | 32 | mod object_all_values_from; 33 | pub use object_all_values_from::*; 34 | 35 | mod object_has_value; 36 | pub use object_has_value::*; 37 | 38 | mod object_has_self; 39 | pub use object_has_self::*; 40 | 41 | /// Class construction based on instances 42 | mod object_one_of; 43 | pub use object_one_of::*; 44 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_all_values_from.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor, ClassIRI, ObjectPropertyConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectAllValuesFrom { 5 | #[serde(rename = "objectProperty")] 6 | pub object_property: ObjectPropertyConstructor, 7 | #[serde(rename = "class_iri")] 8 | pub class_iri: ClassIRI, 9 | pub annotations: Vec, 10 | } 11 | 12 | impl ObjectAllValuesFrom { 13 | pub fn new( 14 | object_property: ObjectPropertyConstructor, 15 | cls: ClassIRI, 16 | annotations: Vec, 17 | ) -> Self { 18 | Self { 19 | object_property, 20 | class_iri: cls, 21 | annotations, 22 | } 23 | } 24 | } 25 | 26 | impl From for Box { 27 | fn from(c: ObjectAllValuesFrom) -> Self { 28 | Box::new(ClassConstructor::ObjectAllValuesFrom(c)) 29 | } 30 | } 31 | 32 | impl From for ClassConstructor { 33 | fn from(c: ObjectAllValuesFrom) -> Self { 34 | ClassConstructor::ObjectAllValuesFrom(c) 35 | } 36 | } 37 | 38 | impl ClassConstructor { 39 | pub fn object_all_values_from(&self) -> Option<&ObjectAllValuesFrom> { 40 | match self { 41 | ClassConstructor::ObjectAllValuesFrom(d) => Some(d), 42 | _ => None, 43 | } 44 | } 45 | } 46 | 47 | #[cfg(feature = "wasm")] 48 | mod wasm { 49 | use wasm_bindgen::prelude::wasm_bindgen; 50 | 51 | #[wasm_bindgen(typescript_custom_section)] 52 | const WASM_API: &'static str = r#" 53 | export type ObjectAllValuesFrom = { 54 | objectProperty: ObjectPropertyConstructor, 55 | class_iri: IRI, 56 | annotations: Array, 57 | }; 58 | "#; 59 | } 60 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_complement_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectComplementOf { 5 | pub cls: Box, 6 | pub annotations: Vec, 7 | } 8 | 9 | impl ObjectComplementOf { 10 | pub fn new(cls: Box, annotations: Vec) -> Self { 11 | Self { cls, annotations } 12 | } 13 | } 14 | 15 | impl From for Box { 16 | fn from(c: ObjectComplementOf) -> Self { 17 | Box::new(ClassConstructor::ObjectComplementOf(c)) 18 | } 19 | } 20 | impl From for ClassConstructor { 21 | fn from(c: ObjectComplementOf) -> Self { 22 | ClassConstructor::ObjectComplementOf(c) 23 | } 24 | } 25 | 26 | impl ClassConstructor { 27 | pub fn object_complement_of(&self) -> Option<&ObjectComplementOf> { 28 | match self { 29 | ClassConstructor::ObjectComplementOf(d) => Some(d), 30 | _ => None, 31 | } 32 | } 33 | } 34 | 35 | #[cfg(feature = "wasm")] 36 | mod wasm { 37 | use wasm_bindgen::prelude::wasm_bindgen; 38 | 39 | #[wasm_bindgen(typescript_custom_section)] 40 | const WASM_API: &'static str = r#" 41 | export type ObjectComplementOf = { 42 | cls: ClassConstructor, 43 | annotations: Array, 44 | }; 45 | "#; 46 | } 47 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_exact_cardinality.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{ClassConstructor, ClassIRI, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectExactCardinality { 5 | pub value: u64, 6 | #[serde(rename = "objectPropertyIRI")] 7 | pub object_property_iri: ObjectPropertyIRI, 8 | pub class_iri: Option, 9 | } 10 | 11 | impl ObjectExactCardinality { 12 | pub fn new(value: u64, object_property_iri: ObjectPropertyIRI, cls: Option) -> Self { 13 | Self { 14 | value, 15 | object_property_iri, 16 | class_iri: cls, 17 | } 18 | } 19 | } 20 | 21 | impl From for Box { 22 | fn from(c: ObjectExactCardinality) -> Self { 23 | Box::new(ClassConstructor::ObjectExactCardinality(c)) 24 | } 25 | } 26 | impl From for ClassConstructor { 27 | fn from(c: ObjectExactCardinality) -> Self { 28 | ClassConstructor::ObjectExactCardinality(c) 29 | } 30 | } 31 | 32 | impl ClassConstructor { 33 | pub fn object_exact_cardinality(&self) -> Option<&ObjectExactCardinality> { 34 | match self { 35 | ClassConstructor::ObjectExactCardinality(d) => Some(d), 36 | _ => None, 37 | } 38 | } 39 | } 40 | 41 | #[cfg(feature = "wasm")] 42 | mod wasm { 43 | use wasm_bindgen::prelude::wasm_bindgen; 44 | 45 | #[wasm_bindgen(typescript_custom_section)] 46 | const WASM_API: &'static str = r#" 47 | /** 48 | * 49 | */ 50 | export type ObjectExactCardinality = { 51 | value: number, 52 | objectPropertyIRI: IRI, 53 | cls: IRI | undefined, 54 | } 55 | "#; 56 | } 57 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_has_self.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor, ObjectPropertyConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectHasSelf { 5 | #[serde(rename = "objectProperty")] 6 | pub object_property: ObjectPropertyConstructor, 7 | pub annotations: Vec, 8 | } 9 | 10 | impl ObjectHasSelf { 11 | pub fn new(object_property: ObjectPropertyConstructor, annotations: Vec) -> Self { 12 | Self { 13 | object_property, 14 | annotations, 15 | } 16 | } 17 | } 18 | 19 | impl From for Box { 20 | fn from(c: ObjectHasSelf) -> Self { 21 | Box::new(ClassConstructor::ObjectHasSelf(c)) 22 | } 23 | } 24 | impl From for ClassConstructor { 25 | fn from(c: ObjectHasSelf) -> Self { 26 | ClassConstructor::ObjectHasSelf(c) 27 | } 28 | } 29 | 30 | impl ClassConstructor { 31 | pub fn object_has_self(&self) -> Option<&ObjectHasSelf> { 32 | match self { 33 | ClassConstructor::ObjectHasSelf(d) => Some(d), 34 | _ => None, 35 | } 36 | } 37 | } 38 | 39 | #[cfg(feature = "wasm")] 40 | mod wasm { 41 | use wasm_bindgen::prelude::wasm_bindgen; 42 | #[wasm_bindgen(typescript_custom_section)] 43 | const WASM_API: &'static str = r#" 44 | export type ObjectHasSelf = { 45 | objectProperty: ObjectPropertyConstructor, 46 | annotations: Array 47 | }; 48 | "#; 49 | } 50 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_has_value.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor, LiteralOrIRI, ObjectPropertyConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectHasValue { 5 | #[serde(rename = "objectProperty")] 6 | pub object_property: ObjectPropertyConstructor, 7 | #[serde(rename = "valueOrIRI")] 8 | pub value_or_iri: LiteralOrIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl ObjectHasValue { 14 | pub fn new( 15 | object_property: ObjectPropertyConstructor, 16 | value_or_iri: LiteralOrIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | object_property, 21 | value_or_iri, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | impl From for Box { 28 | fn from(c: ObjectHasValue) -> Self { 29 | Box::new(ClassConstructor::ObjectHasValue(c)) 30 | } 31 | } 32 | impl From for ClassConstructor { 33 | fn from(c: ObjectHasValue) -> Self { 34 | ClassConstructor::ObjectHasValue(c) 35 | } 36 | } 37 | 38 | impl ClassConstructor { 39 | pub fn object_has_value(&self) -> Option<&ObjectHasValue> { 40 | match self { 41 | ClassConstructor::ObjectHasValue(d) => Some(d), 42 | _ => None, 43 | } 44 | } 45 | } 46 | 47 | #[cfg(feature = "wasm")] 48 | mod wasm { 49 | use wasm_bindgen::prelude::wasm_bindgen; 50 | #[wasm_bindgen(typescript_custom_section)] 51 | const WASM_API: &'static str = r#" 52 | export type ObjectHasValue = { 53 | objectProperty: ObjectPropertyConstructor, 54 | valueOrIRI: Value | IRI, 55 | annotations: Array 56 | }; 57 | "#; 58 | } 59 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_intersection_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectIntersectionOf { 5 | pub classes: Vec, 6 | pub annotations: Vec, 7 | } 8 | 9 | impl ObjectIntersectionOf { 10 | pub fn new(classes: Vec, annotations: Vec) -> Self { 11 | Self { 12 | classes, 13 | annotations, 14 | } 15 | } 16 | } 17 | 18 | impl From for Box { 19 | fn from(c: ObjectIntersectionOf) -> Self { 20 | Box::new(ClassConstructor::ObjectIntersectionOf(c)) 21 | } 22 | } 23 | 24 | impl From for ClassConstructor { 25 | fn from(c: ObjectIntersectionOf) -> Self { 26 | ClassConstructor::ObjectIntersectionOf(c) 27 | } 28 | } 29 | 30 | impl ClassConstructor { 31 | pub fn object_intersection_of(&self) -> Option<&ObjectIntersectionOf> { 32 | match self { 33 | ClassConstructor::ObjectIntersectionOf(d) => Some(d), 34 | _ => None, 35 | } 36 | } 37 | } 38 | 39 | #[cfg(feature = "wasm")] 40 | mod wasm { 41 | use wasm_bindgen::prelude::wasm_bindgen; 42 | 43 | #[wasm_bindgen(typescript_custom_section)] 44 | const WASM_API: &'static str = r#" 45 | export type ObjectIntersectionOf = { 46 | classes: Array, 47 | annotations: Array 48 | }; 49 | "#; 50 | } 51 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_max_cardinality.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{ClassConstructor, ClassIRI, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectMaxCardinality { 5 | pub value: u64, 6 | #[serde(rename = "objectPropertyIRI")] 7 | pub object_property_iri: ObjectPropertyIRI, 8 | #[serde(rename = "classIRI")] 9 | pub class_iri: Option, 10 | } 11 | 12 | impl ObjectMaxCardinality { 13 | pub fn new( 14 | value: u64, 15 | object_property_iri: ObjectPropertyIRI, 16 | class_iri: Option, 17 | ) -> Self { 18 | Self { 19 | value, 20 | object_property_iri, 21 | class_iri, 22 | } 23 | } 24 | } 25 | 26 | impl From for Box { 27 | fn from(c: ObjectMaxCardinality) -> Self { 28 | Box::new(ClassConstructor::ObjectMaxCardinality(c)) 29 | } 30 | } 31 | impl From for ClassConstructor { 32 | fn from(c: ObjectMaxCardinality) -> Self { 33 | ClassConstructor::ObjectMaxCardinality(c) 34 | } 35 | } 36 | 37 | impl ClassConstructor { 38 | pub fn object_max_cardinality(&self) -> Option<&ObjectMaxCardinality> { 39 | match self { 40 | ClassConstructor::ObjectMaxCardinality(d) => Some(d), 41 | _ => None, 42 | } 43 | } 44 | } 45 | 46 | #[cfg(feature = "wasm")] 47 | mod wasm { 48 | use wasm_bindgen::prelude::wasm_bindgen; 49 | #[wasm_bindgen(typescript_custom_section)] 50 | const WASM_API: &'static str = r#" 51 | /** 52 | */ 53 | export type ObjectMaxCardinality = { 54 | value: number, 55 | objectPropertyIRI: IRI, 56 | classIRI: IRI | undefined 57 | }; 58 | "#; 59 | } 60 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_min_cardinality.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{ClassConstructor, ClassIRI, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectMinCardinality { 5 | pub value: u64, 6 | #[serde(rename = "objectPropertyIRI")] 7 | pub object_property_iri: ObjectPropertyIRI, 8 | #[serde(rename = "classIRI")] 9 | pub class_iri: Option, 10 | } 11 | 12 | impl ObjectMinCardinality { 13 | pub fn new( 14 | value: u64, 15 | object_property_iri: ObjectPropertyIRI, 16 | class_iri: Option, 17 | ) -> Self { 18 | Self { 19 | value, 20 | object_property_iri, 21 | class_iri, 22 | } 23 | } 24 | } 25 | 26 | impl From for Box { 27 | fn from(c: ObjectMinCardinality) -> Self { 28 | Box::new(ClassConstructor::ObjectMinCardinality(c)) 29 | } 30 | } 31 | impl From for ClassConstructor { 32 | fn from(c: ObjectMinCardinality) -> Self { 33 | ClassConstructor::ObjectMinCardinality(c) 34 | } 35 | } 36 | 37 | impl ClassConstructor { 38 | pub fn object_min_cardinality(&self) -> Option<&ObjectMinCardinality> { 39 | match self { 40 | ClassConstructor::ObjectMinCardinality(d) => Some(d), 41 | _ => None, 42 | } 43 | } 44 | } 45 | 46 | #[cfg(feature = "wasm")] 47 | mod wasm { 48 | use wasm_bindgen::prelude::wasm_bindgen; 49 | 50 | #[wasm_bindgen(typescript_custom_section)] 51 | const WASM_API: &'static str = r#" 52 | /** 53 | */ 54 | export type ObjectMinCardinality = { 55 | value: number, 56 | objectPropertyIRI: IRI, 57 | classIRI: IRI | undefined 58 | }; 59 | "#; 60 | } 61 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_one_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor, IndividualIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectOneOf { 5 | #[serde(rename = "individualIRIs")] 6 | pub individuals: Vec, 7 | pub annotations: Vec, 8 | } 9 | 10 | impl ObjectOneOf { 11 | pub fn new(individuals: Vec, annotations: Vec) -> Self { 12 | Self { 13 | individuals, 14 | annotations, 15 | } 16 | } 17 | } 18 | 19 | impl From for Box { 20 | fn from(c: ObjectOneOf) -> Self { 21 | Box::new(ClassConstructor::ObjectOneOf(c)) 22 | } 23 | } 24 | 25 | impl From for ClassConstructor { 26 | fn from(c: ObjectOneOf) -> Self { 27 | ClassConstructor::ObjectOneOf(c) 28 | } 29 | } 30 | 31 | impl ClassConstructor { 32 | pub fn object_one_of(&self) -> Option<&ObjectOneOf> { 33 | match self { 34 | ClassConstructor::ObjectOneOf(d) => Some(d), 35 | _ => None, 36 | } 37 | } 38 | } 39 | 40 | #[cfg(feature = "wasm")] 41 | mod wasm { 42 | use wasm_bindgen::prelude::wasm_bindgen; 43 | #[wasm_bindgen(typescript_custom_section)] 44 | const WASM_API: &'static str = r#" 45 | export type ObjectOneOf = { 46 | individualIRIs: Array, 47 | annotations: Array 48 | }; 49 | "#; 50 | } 51 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_some_values_from.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor, ClassIRI, ObjectPropertyConstructor}; 2 | 3 | /// Class construction based on properties. 4 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 5 | pub struct ObjectSomeValuesFrom { 6 | #[serde(rename = "objectProperty")] 7 | pub object_property: ObjectPropertyConstructor, 8 | #[serde(rename = "classIRI")] 9 | pub class_iri: ClassIRI, 10 | pub annotations: Vec, 11 | } 12 | 13 | impl ObjectSomeValuesFrom { 14 | pub fn new( 15 | object_property: ObjectPropertyConstructor, 16 | cls: ClassIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | object_property, 21 | class_iri: cls, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | impl From for ClassConstructor { 28 | fn from(c: ObjectSomeValuesFrom) -> Self { 29 | ClassConstructor::ObjectSomeValuesFrom(c) 30 | } 31 | } 32 | 33 | impl From for Box { 34 | fn from(c: ObjectSomeValuesFrom) -> Self { 35 | Box::new(ClassConstructor::ObjectSomeValuesFrom(c)) 36 | } 37 | } 38 | 39 | impl ClassConstructor { 40 | pub fn object_some_values_from(&self) -> Option<&ObjectSomeValuesFrom> { 41 | match self { 42 | ClassConstructor::ObjectSomeValuesFrom(d) => Some(d), 43 | _ => None, 44 | } 45 | } 46 | } 47 | 48 | #[cfg(feature = "wasm")] 49 | mod wasm { 50 | use wasm_bindgen::prelude::wasm_bindgen; 51 | 52 | #[wasm_bindgen(typescript_custom_section)] 53 | const WASM_API: &'static str = r#" 54 | export type ObjectSomeValuesFrom = { 55 | objectProperty: ObjectPropertyConstructor, 56 | classIRI: IRI, 57 | annotations: Array, 58 | }; 59 | "#; 60 | } 61 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/object_union_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassConstructor}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectUnionOf { 5 | pub classes: Vec, 6 | pub annotations: Vec, 7 | } 8 | 9 | impl ObjectUnionOf { 10 | pub fn new(classes: Vec, annotations: Vec) -> Self { 11 | Self { 12 | classes, 13 | annotations, 14 | } 15 | } 16 | } 17 | 18 | impl From for ClassConstructor { 19 | fn from(c: ObjectUnionOf) -> Self { 20 | ClassConstructor::ObjectUnionOf(c) 21 | } 22 | } 23 | impl From for Box { 24 | fn from(c: ObjectUnionOf) -> Self { 25 | Box::new(ClassConstructor::ObjectUnionOf(c)) 26 | } 27 | } 28 | 29 | impl ClassConstructor { 30 | pub fn object_union_of(&self) -> Option<&ObjectUnionOf> { 31 | match self { 32 | ClassConstructor::ObjectUnionOf(d) => Some(d), 33 | _ => None, 34 | } 35 | } 36 | } 37 | 38 | #[cfg(feature = "wasm")] 39 | mod wasm { 40 | use wasm_bindgen::prelude::wasm_bindgen; 41 | 42 | #[wasm_bindgen(typescript_custom_section)] 43 | const WASM_API: &'static str = r#" 44 | export type ObjectUnionOf = { 45 | classes: Array, 46 | annotations: Array, 47 | }; 48 | "#; 49 | } 50 | -------------------------------------------------------------------------------- /src/owl/classes/constructors/sub_class_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ClassConstructor}; 2 | 3 | /// Defines that the subject is a sub class of the object. 4 | /// 5 | /// Structure `(subject, object, annotations)`. 6 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 7 | pub struct SubClassOf { 8 | #[serde(rename = "cls")] 9 | pub cls: Box, 10 | #[serde(rename = "parentClass")] 11 | pub parent_class: Box, 12 | #[serde(rename = "annotations")] 13 | pub annotations: Vec, 14 | } 15 | 16 | impl SubClassOf { 17 | pub fn new( 18 | cls: Box, 19 | parent_class: Box, 20 | annotations: Vec, 21 | ) -> Self { 22 | Self { 23 | cls, 24 | parent_class, 25 | annotations, 26 | } 27 | } 28 | } 29 | 30 | impl From for Box { 31 | fn from(sco: SubClassOf) -> Self { 32 | Box::new(ClassConstructor::SubClassOf(sco)) 33 | } 34 | } 35 | impl From for ClassConstructor { 36 | fn from(sco: SubClassOf) -> Self { 37 | ClassConstructor::SubClassOf(sco) 38 | } 39 | } 40 | 41 | impl ClassConstructor { 42 | pub fn sub_class_of(&self) -> Option<&SubClassOf> { 43 | match self { 44 | ClassConstructor::SubClassOf(s) => Some(s), 45 | _ => None, 46 | } 47 | } 48 | } 49 | 50 | impl From for Axiom { 51 | fn from(sco: SubClassOf) -> Self { 52 | Axiom::SubClassOf(sco) 53 | } 54 | } 55 | 56 | #[cfg(feature = "wasm")] 57 | mod wasm { 58 | use wasm_bindgen::prelude::wasm_bindgen; 59 | #[wasm_bindgen(typescript_custom_section)] 60 | const WASM_API: &'static str = r#" 61 | export type SubClassOf = { 62 | cls: ClassConstructor, 63 | parentClass: ClassConstructor, 64 | annotations: Array, 65 | }; 66 | "#; 67 | } 68 | -------------------------------------------------------------------------------- /src/owl/classes/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{DataSomeValuesFrom, IRI}; 2 | use serde::{Deserialize, Serialize}; 3 | use std::fmt::Display; 4 | 5 | mod constructors; 6 | pub use constructors::*; 7 | 8 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] 9 | pub struct ClassIRI(IRI); 10 | 11 | impl Display for ClassIRI { 12 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 13 | write!(f, "{}", self.0) 14 | } 15 | } 16 | 17 | impl ClassIRI { 18 | pub fn as_iri(&self) -> &IRI { 19 | &self.0 20 | } 21 | pub fn as_str(&self) -> &str { 22 | self.as_iri().as_str() 23 | } 24 | } 25 | 26 | impl From for ClassIRI { 27 | fn from(iri: IRI) -> Self { 28 | Self(iri) 29 | } 30 | } 31 | 32 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 33 | pub enum ClassConstructor { 34 | IRI(ClassIRI), 35 | SubClassOf(SubClassOf), 36 | DataSomeValuesFrom(DataSomeValuesFrom), 37 | EquivalentClasses(EquivalentClasses), 38 | DisjointClasses(DisjointClasses), 39 | ObjectComplementOf(ObjectComplementOf), 40 | ObjectIntersectionOf(ObjectIntersectionOf), 41 | ObjectUnionOf(ObjectUnionOf), 42 | ObjectSomeValuesFrom(ObjectSomeValuesFrom), 43 | ObjectMaxCardinality(ObjectMaxCardinality), 44 | ObjectMinCardinality(ObjectMinCardinality), 45 | ObjectExactCardinality(ObjectExactCardinality), 46 | ObjectAllValuesFrom(ObjectAllValuesFrom), 47 | ObjectOneOf(ObjectOneOf), 48 | ObjectHasValue(ObjectHasValue), 49 | ObjectHasSelf(ObjectHasSelf), 50 | } 51 | 52 | impl From for Box { 53 | fn from(iri: IRI) -> Self { 54 | Box::new(ClassConstructor::IRI(iri.into())) 55 | } 56 | } 57 | impl From for ClassConstructor { 58 | fn from(iri: IRI) -> Self { 59 | ClassConstructor::IRI(iri.into()) 60 | } 61 | } 62 | impl From for Box { 63 | fn from(iri: ClassIRI) -> Self { 64 | Box::new(ClassConstructor::IRI(iri)) 65 | } 66 | } 67 | impl From for ClassConstructor { 68 | fn from(iri: ClassIRI) -> Self { 69 | ClassConstructor::IRI(iri) 70 | } 71 | } 72 | 73 | impl ClassConstructor { 74 | pub fn is_iri(&self, iri: &IRI) -> bool { 75 | match self { 76 | Self::IRI(i) => i.as_iri() == iri, 77 | _ => false, 78 | } 79 | } 80 | pub fn iri(&self) -> Option<&ClassIRI> { 81 | match self { 82 | Self::IRI(iri) => Some(iri), 83 | _ => None, 84 | } 85 | } 86 | } 87 | 88 | // from data values 89 | 90 | impl From for ClassConstructor { 91 | fn from(c: DataSomeValuesFrom) -> Self { 92 | ClassConstructor::DataSomeValuesFrom(c) 93 | } 94 | } 95 | impl From for Box { 96 | fn from(c: DataSomeValuesFrom) -> Self { 97 | Box::new(ClassConstructor::DataSomeValuesFrom(c)) 98 | } 99 | } 100 | 101 | #[cfg(feature = "wasm")] 102 | mod wasm { 103 | use wasm_bindgen::prelude::wasm_bindgen; 104 | 105 | #[wasm_bindgen(typescript_custom_section)] 106 | const WASM_API: &'static str = r#" 107 | export interface ClassConstructor { 108 | IRI?: IRI 109 | SubClassOf?: SubClassOf 110 | DataSomeValuesFrom?: DataSomeValuesFrom 111 | EquivalentClasses?: EquivalentClasses 112 | DisjointClasses?: DisjointClasses 113 | ObjectComplementOf?: ObjectComplementOf 114 | ObjectIntersectionOf?: ObjectIntersectionOf 115 | ObjectUnionOf?: ObjectUnionOf 116 | ObjectSomeValuesFrom?: ObjectSomeValuesFrom 117 | ObjectMaxCardinality?: ObjectMaxCardinality 118 | ObjectMinCardinality?: ObjectMinCardinality 119 | ObjectExactCardinality?: ObjectExactCardinality 120 | ObjectAllValuesFrom?: ObjectAllValuesFrom 121 | ObjectOneOf?: ObjectOneOf 122 | ObjectHasValue?: ObjectHasValue 123 | ObjectHasSelf?: ObjectHasSelf 124 | } 125 | 126 | interface ClassConstructorMatcher { 127 | IRI?: (c: IRI) => R 128 | SubClassOf?: (c: SubClassOf) => R 129 | DataSomeValuesFrom?: (c: DataSomeValuesFrom) => R 130 | EquivalentClasses?: (c: EquivalentClasses) => R 131 | DisjointClasses?: (c: DisjointClasses) => R 132 | ObjectComplementOf?: (c: ObjectComplementOf) => R 133 | ObjectIntersectionOf?: (c: ObjectIntersectionOf) => R 134 | ObjectUnionOf?: (c: ObjectUnionOf) => R 135 | ObjectSomeValuesFrom?: (c: ObjectSomeValuesFrom) => R 136 | ObjectMaxCardinality?: (c: ObjectMaxCardinality) => R 137 | ObjectMinCardinality?: (c: ObjectMinCardinality) => R 138 | ObjectExactCardinality?: (c: ObjectExactCardinality) => R 139 | ObjectAllValuesFrom?: (c: ObjectAllValuesFrom) => R 140 | ObjectOneOf?: (c: ObjectOneOf) => R 141 | ObjectHasValue?: (c: ObjectHasValue) => R 142 | ObjectHasSelf?: (c: ObjectHasSelf) => R 143 | } 144 | 145 | export function matchClassConst(classConstructor: ClassConstructor, matcher: ClassConstructorMatcher): R 146 | "#; 147 | } 148 | 149 | #[cfg(test)] 150 | mod tests { 151 | use super::*; 152 | 153 | #[test] 154 | pub fn test_ser_de_class_iri() { 155 | let iri: ClassIRI = IRI::new("https://test.org#asdf").unwrap().into(); 156 | 157 | let json = serde_json::to_string(&iri).unwrap(); 158 | 159 | assert_eq!(json, r#"{"_type":"IRI","string":"https://test.org#asdf"}"#); 160 | 161 | let json = r#"{"_type":"IRI","string":"https://test.org#asdf"}"#; 162 | let iri1: ClassIRI = serde_json::from_str(json).unwrap(); 163 | 164 | assert_eq!(iri1, iri) 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/data_complement_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, DataPropertyIRI}; 2 | 3 | use super::DatatypeDefinitionConstructor; 4 | 5 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 6 | pub struct DataComplementOf { 7 | #[serde(rename = "dataPropertyIRI")] 8 | pub data_property_iri: DataPropertyIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl DataComplementOf { 14 | pub fn new(data_property_iri: DataPropertyIRI, annotations: Vec) -> Self { 15 | Self { 16 | data_property_iri, 17 | annotations, 18 | } 19 | } 20 | } 21 | 22 | impl From for Box { 23 | fn from(c: DataComplementOf) -> Self { 24 | DatatypeDefinitionConstructor::DataComplementOf(c).into() 25 | } 26 | } 27 | 28 | impl From for DatatypeDefinitionConstructor { 29 | fn from(c: DataComplementOf) -> Self { 30 | DatatypeDefinitionConstructor::DataComplementOf(c) 31 | } 32 | } 33 | 34 | #[cfg(feature = "wasm")] 35 | mod wasm { 36 | use wasm_bindgen::prelude::wasm_bindgen; 37 | 38 | #[wasm_bindgen(typescript_custom_section)] 39 | const WASM_API: &'static str = r#" 40 | export type DataComplementOf = { 41 | dataPropertyIRI: IRI, 42 | annotations: Array, 43 | }; 44 | "#; 45 | } 46 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/data_intersection_of.rs: -------------------------------------------------------------------------------- 1 | use super::DatatypeDefinitionConstructor; 2 | use crate::owl::{Annotation, DataPropertyIRI}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 5 | pub struct DataIntersectionOf { 6 | #[serde(rename = "dataPropertyIRI")] 7 | pub data_property_iri: DataPropertyIRI, 8 | #[serde(rename = "datatype")] 9 | pub datatype: Box, 10 | #[serde(rename = "annotations")] 11 | pub annotations: Vec, 12 | } 13 | 14 | impl DataIntersectionOf { 15 | pub fn new( 16 | iri: DataPropertyIRI, 17 | datatype: Box, 18 | annotations: Vec, 19 | ) -> Self { 20 | Self { 21 | data_property_iri: iri, 22 | datatype, 23 | annotations, 24 | } 25 | } 26 | } 27 | 28 | impl From for Box { 29 | fn from(c: DataIntersectionOf) -> Self { 30 | DatatypeDefinitionConstructor::DataIntersectionOf(c).into() 31 | } 32 | } 33 | 34 | impl From for DatatypeDefinitionConstructor { 35 | fn from(c: DataIntersectionOf) -> Self { 36 | DatatypeDefinitionConstructor::DataIntersectionOf(c) 37 | } 38 | } 39 | 40 | #[cfg(feature = "wasm")] 41 | mod wasm { 42 | use wasm_bindgen::prelude::wasm_bindgen; 43 | 44 | #[wasm_bindgen(typescript_custom_section)] 45 | const WASM_API: &'static str = r#" 46 | export type DataIntersectionOf = { 47 | dataPropertyIRI: IRI, 48 | datatype: DatatypeDefinitionConstructor, 49 | annotations: Array, 50 | }; 51 | "#; 52 | } 53 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/data_one_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Literal}; 2 | 3 | use super::DatatypeDefinitionConstructor; 4 | 5 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 6 | pub struct DataOneOf { 7 | #[serde(rename = "literals")] 8 | pub literals: Vec, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl DataOneOf { 14 | pub fn new(literals: Vec, annotations: Vec) -> Self { 15 | Self { 16 | literals, 17 | annotations, 18 | } 19 | } 20 | } 21 | 22 | impl From for Box { 23 | fn from(c: DataOneOf) -> Self { 24 | DatatypeDefinitionConstructor::DataOneOf(c).into() 25 | } 26 | } 27 | impl From for DatatypeDefinitionConstructor { 28 | fn from(c: DataOneOf) -> Self { 29 | DatatypeDefinitionConstructor::DataOneOf(c) 30 | } 31 | } 32 | 33 | #[cfg(feature = "wasm")] 34 | mod wasm { 35 | use wasm_bindgen::prelude::wasm_bindgen; 36 | 37 | #[wasm_bindgen(typescript_custom_section)] 38 | const WASM_API: &'static str = r#" 39 | /** 40 | * List of literals. 41 | */ 42 | export type DataOneOf = { 43 | literals: Array, 44 | annotations: Array, 45 | }; 46 | "#; 47 | } 48 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/data_some_values_from.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, DataPropertyIRI, DatatypeRestriction}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct DataSomeValuesFrom { 5 | #[serde(rename = "dataPropertyIRI")] 6 | pub data_property_iri: DataPropertyIRI, 7 | #[serde(rename = "restriction")] 8 | pub restriction: DatatypeRestriction, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl DataSomeValuesFrom { 14 | pub fn new( 15 | data_property_iri: DataPropertyIRI, 16 | restriction: DatatypeRestriction, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | data_property_iri, 21 | restriction, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[cfg(feature = "wasm")] 28 | mod wasm { 29 | use wasm_bindgen::prelude::wasm_bindgen; 30 | #[wasm_bindgen(typescript_custom_section)] 31 | const WASM_API: &'static str = r#" 32 | export type DataSomeValuesFrom = { 33 | dataPropertyIRI: IRI, 34 | restriction: DatatypeRestriction, 35 | annotations: Array, 36 | }; 37 | "#; 38 | } 39 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/data_union_of.rs: -------------------------------------------------------------------------------- 1 | use super::DatatypeDefinitionConstructor; 2 | use crate::owl::{Annotation, DataPropertyIRI}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 5 | pub struct DataUnionOf { 6 | #[serde(rename = "dataPropertyIRI")] 7 | pub data_property_iri: DataPropertyIRI, 8 | #[serde(rename = "datatype")] 9 | pub datatype: Box, 10 | #[serde(rename = "annotations")] 11 | pub annotations: Vec, 12 | } 13 | 14 | impl DataUnionOf { 15 | pub fn new( 16 | iri: DataPropertyIRI, 17 | datatype: Box, 18 | annotations: Vec, 19 | ) -> Self { 20 | Self { 21 | data_property_iri: iri, 22 | datatype, 23 | annotations, 24 | } 25 | } 26 | } 27 | 28 | impl From for Box { 29 | fn from(c: DataUnionOf) -> Self { 30 | DatatypeDefinitionConstructor::DataUnionOf(c).into() 31 | } 32 | } 33 | impl From for DatatypeDefinitionConstructor { 34 | fn from(c: DataUnionOf) -> Self { 35 | DatatypeDefinitionConstructor::DataUnionOf(c) 36 | } 37 | } 38 | 39 | #[cfg(feature = "wasm")] 40 | mod wasm { 41 | use wasm_bindgen::prelude::wasm_bindgen; 42 | 43 | #[wasm_bindgen(typescript_custom_section)] 44 | const WASM_API: &'static str = r#" 45 | export type DataUnionOf = { 46 | dataPropertyIRI: IRI, 47 | datatype: DatatypeDefinitionConstructor, 48 | annotations: Array, 49 | }; 50 | "#; 51 | } 52 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/datatype_definition.rs: -------------------------------------------------------------------------------- 1 | use super::{DataComplementOf, DataIntersectionOf, DataOneOf, DataUnionOf, DatatypeRestriction}; 2 | use crate::owl::{Annotation, DataPropertyIRI}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 5 | pub enum DatatypeDefinitionConstructor { 6 | DatatypeRestriction(DatatypeRestriction), 7 | DataComplementOf(DataComplementOf), 8 | DataIntersectionOf(DataIntersectionOf), 9 | DataUnionOf(DataUnionOf), 10 | DataOneOf(DataOneOf), 11 | } 12 | 13 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 14 | pub struct DatatypeDefinition { 15 | #[serde(rename = "dataPropertyIRI")] 16 | pub data_property_iri: DataPropertyIRI, 17 | #[serde(rename = "datatype")] 18 | pub datatype: DatatypeDefinitionConstructor, 19 | #[serde(rename = "annotations")] 20 | pub annotations: Vec, 21 | } 22 | 23 | impl DatatypeDefinition { 24 | pub fn new( 25 | data_property_iri: DataPropertyIRI, 26 | datatype_definition: DatatypeDefinitionConstructor, 27 | annotations: Vec, 28 | ) -> Self { 29 | Self { 30 | data_property_iri, 31 | datatype: datatype_definition, 32 | annotations, 33 | } 34 | } 35 | } 36 | 37 | #[cfg(feature = "wasm")] 38 | mod wasm { 39 | use wasm_bindgen::prelude::wasm_bindgen; 40 | 41 | #[wasm_bindgen(typescript_custom_section)] 42 | const WASM_API1: &'static str = r#" 43 | export interface DatatypeDefinitionConstructor { 44 | DatatypeRestriction?: DatatypeRestriction 45 | DataComplementOf?: DataComplementOf 46 | DataIntersectionOf?: DataIntersectionOf 47 | DataUnionOf?: DataUnionOf 48 | DataOneOf?: DataOneOf 49 | } 50 | "#; 51 | 52 | #[wasm_bindgen(typescript_custom_section)] 53 | const WASM_API2: &'static str = r#" 54 | /** 55 | * [DataProperty IRI, DatatypeDefinitionConstructor, annotations] 56 | */ 57 | export type DatatypeDefinition = { 58 | dataPropertyIRI: IRI, 59 | datatype: DatatypeDefinitionConstructor, 60 | annotations: Array, 61 | }; 62 | "#; 63 | } 64 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/datatype_restriction.rs: -------------------------------------------------------------------------------- 1 | use super::DatatypeDefinitionConstructor; 2 | use crate::owl::{Annotation, DatatypeIRI, Literal}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 5 | pub enum Restriction { 6 | Numeric { 7 | #[serde(rename = "datatypeIRI")] 8 | datatype_iri: DatatypeIRI, 9 | #[serde(rename = "value")] 10 | value: Literal, 11 | }, 12 | } 13 | 14 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 15 | pub struct DatatypeRestriction { 16 | #[serde(rename = "datatypeIRI")] 17 | pub datatype_iri: DatatypeIRI, 18 | #[serde(rename = "restrictions")] 19 | pub restrictions: Vec, 20 | #[serde(rename = "annotations")] 21 | pub annotations: Vec, 22 | } 23 | 24 | impl DatatypeRestriction { 25 | pub fn new( 26 | datatype_iri: DatatypeIRI, 27 | restrictions: Vec, 28 | annotations: Vec, 29 | ) -> Self { 30 | Self { 31 | datatype_iri, 32 | restrictions, 33 | annotations, 34 | } 35 | } 36 | } 37 | 38 | impl From for Box { 39 | fn from(c: DatatypeRestriction) -> Self { 40 | DatatypeDefinitionConstructor::DatatypeRestriction(c).into() 41 | } 42 | } 43 | impl From for DatatypeDefinitionConstructor { 44 | fn from(c: DatatypeRestriction) -> Self { 45 | DatatypeDefinitionConstructor::DatatypeRestriction(c) 46 | } 47 | } 48 | 49 | #[cfg(feature = "wasm")] 50 | mod wasm { 51 | use wasm_bindgen::prelude::wasm_bindgen; 52 | 53 | #[wasm_bindgen(typescript_custom_section)] 54 | const WASM_API1: &'static str = r#" 55 | export type Restriction = { Numeric: {datatypeIRI: IRI, value: number} }; 56 | "#; 57 | 58 | #[wasm_bindgen(typescript_custom_section)] 59 | const WASM_API2: &'static str = r#" 60 | export type DatatypeRestriction = { 61 | datatypeIRI: IRI, 62 | restrictions: Array, 63 | annotations: Array, 64 | }; 65 | "#; 66 | } 67 | -------------------------------------------------------------------------------- /src/owl/datatypes/constructors/mod.rs: -------------------------------------------------------------------------------- 1 | mod datatype_definition; 2 | pub use datatype_definition::*; 3 | 4 | mod data_some_values_from; 5 | pub use data_some_values_from::*; 6 | 7 | mod datatype_restriction; 8 | pub use datatype_restriction::*; 9 | 10 | mod data_complement_of; 11 | pub use data_complement_of::*; 12 | 13 | mod data_intersection_of; 14 | pub use data_intersection_of::*; 15 | 16 | mod data_union_of; 17 | pub use data_union_of::*; 18 | 19 | mod data_one_of; 20 | pub use data_one_of::*; 21 | -------------------------------------------------------------------------------- /src/owl/datatypes/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{IndividualIRI, IRI, ResourceId}; 2 | 3 | mod constructors; 4 | pub use constructors::*; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | use super::{Annotation, Axiom, Literal}; 8 | 9 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 10 | pub struct DatatypeIRI(pub IRI); 11 | 12 | impl From for DatatypeIRI { 13 | fn from(iri: IRI) -> Self { 14 | Self(iri) 15 | } 16 | } 17 | impl DatatypeIRI { 18 | pub fn as_iri(&self) -> &IRI { 19 | &self.0 20 | } 21 | } 22 | 23 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 24 | pub struct DataPropertyIRI(IRI); 25 | 26 | impl From for DataPropertyIRI { 27 | fn from(iri: IRI) -> Self { 28 | Self(iri) 29 | } 30 | } 31 | impl DataPropertyIRI { 32 | pub fn as_iri(&self) -> &IRI { 33 | &self.0 34 | } 35 | } 36 | 37 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 38 | pub struct DataPropertyAssertion { 39 | /// Known IDs of reifications of this assertion. 40 | #[serde(rename = "resourceIds")] 41 | pub resource_ids: Vec, 42 | #[serde(rename = "dataPropertyIRI")] 43 | pub iri: DataPropertyIRI, 44 | #[serde(rename = "subjectIRI")] 45 | pub subject: IndividualIRI, 46 | #[serde(rename = "value")] 47 | pub value: Literal, 48 | #[serde(rename = "annotations")] 49 | pub annotations: Vec, 50 | } 51 | 52 | impl From for Axiom { 53 | fn from(dpa: DataPropertyAssertion) -> Self { 54 | Axiom::DataPropertyAssertion(dpa) 55 | } 56 | } 57 | 58 | impl DataPropertyAssertion { 59 | pub fn new( 60 | iri: DataPropertyIRI, 61 | subject: IndividualIRI, 62 | value: Literal, 63 | annotations: Vec, 64 | resource_ids: Vec, 65 | ) -> Self { 66 | Self { 67 | iri, 68 | subject, 69 | value, 70 | annotations, 71 | resource_ids 72 | } 73 | } 74 | } 75 | 76 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 77 | pub struct NegativeDataPropertyAssertion { 78 | #[serde(rename = "dataPropertyIRI")] 79 | pub data_property_iri: DataPropertyIRI, 80 | #[serde(rename = "subjectIRI")] 81 | pub subject: IndividualIRI, 82 | #[serde(rename = "value")] 83 | pub value: Literal, 84 | #[serde(rename = "annotations")] 85 | pub annotations: Vec, 86 | } 87 | 88 | impl NegativeDataPropertyAssertion { 89 | pub fn new( 90 | iri: DataPropertyIRI, 91 | subject: IndividualIRI, 92 | value: Literal, 93 | annotations: Vec, 94 | ) -> Self { 95 | Self { 96 | data_property_iri: iri, 97 | subject, 98 | value, 99 | annotations, 100 | } 101 | } 102 | } 103 | 104 | #[cfg(feature = "wasm")] 105 | mod wasm { 106 | use wasm_bindgen::prelude::wasm_bindgen; 107 | 108 | #[wasm_bindgen(typescript_custom_section)] 109 | const WASM_API_1: &'static str = r#" 110 | /** 111 | * Assigns a value (of the property with iri) to a subject Individual. 112 | */ 113 | export type DataPropertyAssertion = { 114 | /** 115 | * IRI of the property. 116 | */ 117 | dataPropertyIRI: IRI, 118 | /** 119 | * IRI of the subject Individual. 120 | */ 121 | subjectIRI: IRI, 122 | value: Value, 123 | annotations: Array, 124 | }; 125 | "#; 126 | 127 | #[wasm_bindgen(typescript_custom_section)] 128 | const WASM_API_2: &'static str = r#" 129 | /** 130 | * Opposite of DataPropertyAssertion. 131 | */ 132 | export type NegativeDataPropertyAssertion = { 133 | /** 134 | * IRI of the property. 135 | */ 136 | dataPropertyIRI: IRI, 137 | /** 138 | * IRI of the subject Individual. 139 | */ 140 | subjectIRI: IRI, 141 | value: Value, 142 | annotations: Array, 143 | } 144 | "#; 145 | } 146 | -------------------------------------------------------------------------------- /src/owl/individual/axioms.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ClassConstructor, EquivalentClasses, IndividualIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct SameIndividual { 5 | #[serde(rename = "individualIRI1")] 6 | pub individual1: IndividualIRI, 7 | #[serde(rename = "individualIRI2")] 8 | pub individual2: IndividualIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl SameIndividual { 14 | pub fn new( 15 | individual1: IndividualIRI, 16 | individual2: IndividualIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | individual1, 21 | individual2, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 28 | pub struct DifferentIndividuals { 29 | #[serde(rename = "individualIRI1")] 30 | pub individual1: IndividualIRI, 31 | #[serde(rename = "individualIRI2")] 32 | pub individual2: IndividualIRI, 33 | #[serde(rename = "annotations")] 34 | pub annotations: Vec, 35 | } 36 | 37 | impl DifferentIndividuals { 38 | pub fn new( 39 | individual1: IndividualIRI, 40 | individual2: IndividualIRI, 41 | annotations: Vec, 42 | ) -> Self { 43 | Self { 44 | individual1, 45 | individual2, 46 | annotations, 47 | } 48 | } 49 | } 50 | 51 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 52 | pub struct ClassAssertion { 53 | #[serde(rename = "cls")] 54 | pub cls: ClassConstructor, 55 | #[serde(rename = "individualIRI")] 56 | pub individual: IndividualIRI, 57 | #[serde(rename = "annotations")] 58 | pub annotations: Vec, 59 | } 60 | 61 | impl ClassAssertion { 62 | pub fn new( 63 | cls: ClassConstructor, 64 | individual: IndividualIRI, 65 | annotations: Vec, 66 | ) -> Self { 67 | Self { 68 | cls, 69 | individual, 70 | annotations, 71 | } 72 | } 73 | } 74 | 75 | impl From for Axiom { 76 | fn from(ca: ClassAssertion) -> Self { 77 | Axiom::ClassAssertion(ca) 78 | } 79 | } 80 | 81 | impl From for Axiom { 82 | fn from(ec: EquivalentClasses) -> Self { 83 | Axiom::EquivalentClasses(ec) 84 | } 85 | } 86 | 87 | #[cfg(feature = "wasm")] 88 | mod wasm { 89 | use wasm_bindgen::prelude::wasm_bindgen; 90 | 91 | #[wasm_bindgen(typescript_custom_section)] 92 | const WASM_API1: &'static str = r#" 93 | export type SameIndividual = { 94 | individualIRI1: IRI, 95 | individualIRI2: IRI, 96 | annotations: Array, 97 | }; 98 | "#; 99 | 100 | #[wasm_bindgen(typescript_custom_section)] 101 | const WASM_API2: &'static str = r#" 102 | export type DifferentIndividuals = { 103 | individualIRI1: IRI, 104 | individualIRI2: IRI, 105 | annotations: Array, 106 | }; 107 | "#; 108 | 109 | #[wasm_bindgen(typescript_custom_section)] 110 | const WASM_API3: &'static str = r#" 111 | export type ClassAssertion = { 112 | cls: ClassConstructor, 113 | individualIRI: IRI, 114 | annotations: Array, 115 | }; 116 | "#; 117 | } 118 | -------------------------------------------------------------------------------- /src/owl/individual/mod.rs: -------------------------------------------------------------------------------- 1 | mod axioms; 2 | pub use axioms::*; 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use crate::owl::IRI; 6 | 7 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] 8 | pub struct IndividualIRI(IRI); 9 | 10 | impl From for IndividualIRI { 11 | fn from(iri: IRI) -> Self { 12 | Self(iri) 13 | } 14 | } 15 | impl IndividualIRI { 16 | pub fn as_iri(&self) -> &IRI { 17 | &self.0 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/owl/iri_or_list.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::serializer::IriToTtl; 4 | 5 | use super::IRI; 6 | 7 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 8 | pub enum IRIList { 9 | IRI(IRI), 10 | List(Vec), 11 | } 12 | 13 | impl IriToTtl for IRIList { 14 | fn ttl(&self, imports: &HashMap) -> String { 15 | match self { 16 | IRIList::IRI(iri) => iri.ttl(imports), 17 | IRIList::List(iris) => format!( 18 | "( {} )", 19 | iris.iter() 20 | .map(|iri| iri.ttl(imports)) 21 | .collect::>() 22 | .join(" ") 23 | ), 24 | } 25 | } 26 | } 27 | 28 | #[cfg(test)] 29 | mod tests { 30 | use crate::owl::IRI; 31 | 32 | use super::IRIList; 33 | 34 | #[test] 35 | fn serialize() { 36 | let il = IRIList::List(vec![IRI::new("http://test#").unwrap()]); 37 | assert_eq!(serde_json::to_string(&il).unwrap(), "{\"List\":[{\"_type\":\"IRI\",\"string\":\"http://test#\"}]}"); 38 | let il = IRIList::IRI(IRI::new("http://test#").unwrap()); 39 | assert_eq!(serde_json::to_string(&il).unwrap(), "{\"IRI\":{\"_type\":\"IRI\",\"string\":\"http://test#\"}}"); 40 | } 41 | } 42 | 43 | #[cfg(feature = "wasm")] 44 | mod wasm { 45 | use wasm_bindgen::prelude::wasm_bindgen; 46 | 47 | #[wasm_bindgen(typescript_custom_section)] 48 | const WASM_API: &'static str = r#" 49 | /** 50 | * Either a single IRI or a list of IRIs. 51 | */ 52 | export interface IRIList { 53 | IRI?: IRI, 54 | List?: IRI[], 55 | } 56 | "#; 57 | } 58 | -------------------------------------------------------------------------------- /src/owl/mod.rs: -------------------------------------------------------------------------------- 1 | mod iri; 2 | pub use iri::*; 3 | 4 | mod iri_or_list; 5 | pub use iri_or_list::*; 6 | 7 | pub mod well_known; 8 | 9 | mod value; 10 | pub use value::*; 11 | 12 | mod classes; 13 | pub use classes::*; 14 | 15 | mod individual; 16 | pub use individual::*; 17 | 18 | mod datatypes; 19 | pub use datatypes::*; 20 | 21 | mod ontology; 22 | pub use ontology::*; 23 | 24 | mod axiom; 25 | pub use axiom::*; 26 | 27 | mod properties; 28 | pub use properties::*; 29 | 30 | mod other; 31 | pub use other::*; 32 | 33 | mod lang; 34 | pub use lang::*; 35 | -------------------------------------------------------------------------------- /src/owl/ontology.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::*; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] 5 | pub enum Declaration { 6 | Class { 7 | iri: ClassIRI, 8 | annotations: Vec, 9 | }, 10 | NamedIndividual { 11 | iri: IndividualIRI, 12 | annotations: Vec, 13 | }, 14 | ObjectProperty { 15 | iri: ObjectPropertyIRI, 16 | annotations: Vec, 17 | }, 18 | DataProperty { 19 | iri: DataPropertyIRI, 20 | annotations: Vec, 21 | }, 22 | AnnotationProperty { 23 | iri: AnnotationPropertyIRI, 24 | annotations: Vec, 25 | }, 26 | Datatype { 27 | iri: DatatypeIRI, 28 | annotations: Vec, 29 | }, 30 | } 31 | 32 | impl Declaration { 33 | pub fn annotations(&self) -> &Vec { 34 | match &self { 35 | Declaration::Class { 36 | iri: _, 37 | annotations, 38 | } => annotations, 39 | Declaration::NamedIndividual { 40 | iri: _, 41 | annotations, 42 | } => annotations, 43 | Declaration::ObjectProperty { 44 | iri: _, 45 | annotations, 46 | } => annotations, 47 | Declaration::DataProperty { 48 | iri: _, 49 | annotations, 50 | } => annotations, 51 | Declaration::AnnotationProperty { 52 | iri: _, 53 | annotations, 54 | } => annotations, 55 | Declaration::Datatype { 56 | iri: _, 57 | annotations, 58 | } => annotations, 59 | } 60 | } 61 | } 62 | 63 | #[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)] 64 | pub struct Ontology { 65 | pub(crate) declarations: Vec, 66 | pub(crate) axioms: Vec, 67 | } 68 | 69 | impl Ontology { 70 | pub fn new(declarations: Vec, axioms: Vec) -> Self { 71 | Self { 72 | declarations, 73 | axioms, 74 | } 75 | } 76 | pub fn declarations(&self) -> &Vec { 77 | &self.declarations 78 | } 79 | pub fn axioms(&self) -> &Vec { 80 | &self.axioms 81 | } 82 | pub fn axioms_mut(&mut self) -> &mut Vec { 83 | &mut self.axioms 84 | } 85 | pub fn declarations_mut(&mut self) -> &mut Vec { 86 | &mut self.declarations 87 | } 88 | } 89 | 90 | #[cfg(test)] 91 | mod tests { 92 | use super::*; 93 | 94 | #[test] 95 | pub fn test_ser_de_declaration() { 96 | let d = Declaration::Class { 97 | iri: IRI::new("http://example.com").unwrap().into(), 98 | annotations: vec![], 99 | }; 100 | let json = serde_json::to_string(&d).unwrap(); 101 | assert_eq!( 102 | json, 103 | r#"{"Class":{"iri":{"_type":"IRI","string":"http://example.com"},"annotations":[]}}"# 104 | ); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/owl/other/has_key.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ClassIRI, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct HasKey { 5 | #[serde(rename = "iri")] 6 | pub iri: ClassIRI, 7 | #[serde(rename = "objectProperties")] 8 | pub object_properties: Vec, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl HasKey { 14 | pub fn new( 15 | iri: ClassIRI, 16 | object_properties: Vec, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | iri, 21 | object_properties, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[cfg(feature = "wasm")] 28 | mod wasm { 29 | use wasm_bindgen::prelude::wasm_bindgen; 30 | 31 | #[wasm_bindgen(typescript_custom_section)] 32 | const WASM_API: &'static str = r#" 33 | export type HasKey = { 34 | iri: IRI, 35 | objectProperties: Array, 36 | annotations: Array, 37 | }; 38 | "#; 39 | } 40 | -------------------------------------------------------------------------------- /src/owl/other/mod.rs: -------------------------------------------------------------------------------- 1 | mod has_key; 2 | pub use has_key::*; 3 | -------------------------------------------------------------------------------- /src/owl/properties/annotation.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{AnnotationAssertion, LiteralOrIRI, ResourceId}; 2 | 3 | use super::AnnotationPropertyIRI; 4 | /// Annotations provide metadata to other concepts. They can be assigned to everything. 5 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 6 | pub struct Annotation { 7 | #[serde(rename = "annotationIRI")] 8 | pub iri: AnnotationPropertyIRI, 9 | #[serde(rename = "value")] 10 | pub value: LiteralOrIRI, 11 | #[serde(rename = "annotations")] 12 | pub annotations: Vec>, 13 | } 14 | 15 | impl Annotation { 16 | pub fn new( 17 | iri: AnnotationPropertyIRI, 18 | value: LiteralOrIRI, 19 | annotations: Vec>, 20 | ) -> Self { 21 | Self { 22 | iri, 23 | value, 24 | annotations, 25 | } 26 | } 27 | 28 | /// Turn an annotation into an AnnotationAssertion by combining it with a subject. 29 | /// 30 | /// This slightly breaks with the semantic difference between `Annotation` and `AnnotationAssertion`, 31 | /// as many `Annotation`s in the OWL sense are not "assertions". 32 | /// However this provides an easier to use interface, especially when it comes to reifications. 33 | pub fn to_assertion(self, subject_resource_id: ResourceId) -> AnnotationAssertion { 34 | AnnotationAssertion::new(self.iri, subject_resource_id, self.value, self.annotations.clone().into_iter().map(|n| *n).collect(), vec![]) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/owl/properties/annotation_property.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::Display; 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | use crate::owl::{Axiom, ClassIRI, DatatypeIRI, LiteralOrIRI, IRI, ResourceId}; 6 | 7 | use super::Annotation; 8 | 9 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 10 | pub struct AnnotationPropertyIRI(IRI); 11 | impl AnnotationPropertyIRI { 12 | pub fn as_iri(&self) -> &IRI { 13 | &self.0 14 | } 15 | 16 | pub fn as_str(&self) -> &str { 17 | self.as_iri().as_str() 18 | } 19 | } 20 | impl From for AnnotationPropertyIRI { 21 | fn from(iri: IRI) -> Self { 22 | Self(iri) 23 | } 24 | } 25 | impl Display for AnnotationPropertyIRI { 26 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 27 | write!(f, "{}", self.0) 28 | } 29 | } 30 | 31 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] 32 | pub struct AnnotationPropertyDomain { 33 | #[serde(rename = "annotationIRI")] 34 | pub iri: AnnotationPropertyIRI, 35 | #[serde(rename = "classIRI")] 36 | pub class_iri: ClassIRI, 37 | #[serde(rename = "annotations")] 38 | pub annotations: Vec, 39 | } 40 | 41 | impl AnnotationPropertyDomain { 42 | pub fn new(iri: AnnotationPropertyIRI, cls: ClassIRI, annotations: Vec) -> Self { 43 | Self { 44 | iri, 45 | class_iri: cls, 46 | annotations, 47 | } 48 | } 49 | } 50 | 51 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] 52 | pub struct AnnotationPropertyRange { 53 | #[serde(rename = "annotationIRI")] 54 | pub iri: AnnotationPropertyIRI, 55 | #[serde(rename = "datatypeIRI")] 56 | pub datatype_iri: DatatypeIRI, 57 | #[serde(rename = "annotations")] 58 | pub annotations: Vec, 59 | } 60 | 61 | impl AnnotationPropertyRange { 62 | pub fn new( 63 | iri: AnnotationPropertyIRI, 64 | datatype_iri: DatatypeIRI, 65 | annotations: Vec, 66 | ) -> Self { 67 | Self { 68 | iri, 69 | datatype_iri, 70 | annotations, 71 | } 72 | } 73 | } 74 | 75 | impl From for Axiom { 76 | fn from(a: AnnotationPropertyRange) -> Self { 77 | Self::AnnotationPropertyRange(a) 78 | } 79 | } 80 | 81 | impl From for Axiom { 82 | fn from(a: AnnotationPropertyDomain) -> Self { 83 | Self::AnnotationPropertyDomain(a) 84 | } 85 | } 86 | 87 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 88 | pub struct AnnotationAssertion { 89 | /// Known IDs of reifications of this assertion. 90 | #[serde(rename = "resourceIds")] 91 | pub resource_ids: Vec, 92 | pub subject: ResourceId, 93 | #[serde(rename = "annotationIRI")] 94 | pub iri: AnnotationPropertyIRI, 95 | #[serde(rename = "value")] 96 | pub value: LiteralOrIRI, 97 | #[serde(rename = "annotations")] 98 | pub annotations: Vec, 99 | } 100 | 101 | impl AnnotationAssertion { 102 | pub fn new>( 103 | iri: AnnotationPropertyIRI, 104 | subject: S, 105 | value: LiteralOrIRI, 106 | annotations: Vec, 107 | resource_ids: Vec, 108 | ) -> Self { 109 | Self { 110 | iri, 111 | subject: subject.into(), 112 | value, 113 | annotations, 114 | resource_ids 115 | } 116 | } 117 | } 118 | 119 | impl From for Axiom { 120 | fn from(aa: AnnotationAssertion) -> Self { 121 | Axiom::AnnotationAssertion(aa) 122 | } 123 | } 124 | 125 | #[cfg(feature = "wasm")] 126 | mod wasm { 127 | use wasm_bindgen::prelude::wasm_bindgen; 128 | 129 | #[wasm_bindgen(typescript_custom_section)] 130 | const WASM_API_ANNOTATION_ASSERTION: &'static str = r#" 131 | /** 132 | * Assertion of an AnnotationProperty to some subject 133 | */ 134 | export type AnnotationAssertion = { 135 | /** 136 | * The IRI of this annotation. 137 | */ 138 | annotationIRI: IRI, 139 | /** 140 | * The ResourceId of the subject. 141 | */ 142 | subject: ResourceId, 143 | /** 144 | * The asserted value. 145 | */ 146 | value: LiteralOrIRI, 147 | annotations: Array 148 | }; 149 | export type AnnotationAssertionDomain = { 150 | /** 151 | * The IRI of this annotation. 152 | */ 153 | annotationIRI: IRI, 154 | classIRI: IRI, 155 | annotations: Array 156 | }; 157 | export type AnnotationAssertionRange = { 158 | /** 159 | * The IRI of this annotation. 160 | */ 161 | annotationIRI: IRI, 162 | datatypeIRI: IRI, 163 | annotations: Array 164 | }; 165 | "#; 166 | 167 | #[wasm_bindgen(typescript_custom_section)] 168 | const WASM_API_ANNOTATION: &'static str = r#" 169 | export type Annotation = { 170 | /** 171 | * The annotation IRI. 172 | */ 173 | annotationIRI: IRI, 174 | /** 175 | * The annotation value. 176 | */ 177 | value: LiteralOrIRI, 178 | annotations: Array, 179 | }; 180 | "#; 181 | } 182 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/asymmetric_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct AsymmetricObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl AsymmetricObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | impl From for Axiom { 21 | fn from(aop: AsymmetricObjectProperty) -> Self { 22 | Self::AsymmetricObjectProperty(aop) 23 | } 24 | } 25 | 26 | #[cfg(feature = "wasm")] 27 | mod wasm { 28 | use wasm_bindgen::prelude::wasm_bindgen; 29 | #[wasm_bindgen(typescript_custom_section)] 30 | const WASM_API: &'static str = r#" 31 | export type AsymmetricObjectProperty = { 32 | objectPropertyIRI: IRI, 33 | annotations: Array, 34 | }; 35 | "#; 36 | } 37 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/data_property_domain.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ClassConstructor, DataPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct DataPropertyDomain { 5 | #[serde(rename = "dataPropertyIRI")] 6 | pub iri: DataPropertyIRI, 7 | #[serde(rename = "cls")] 8 | pub cls: ClassConstructor, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl DataPropertyDomain { 14 | pub fn new( 15 | data_property_iri: DataPropertyIRI, 16 | cls: ClassConstructor, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | iri: data_property_iri, 21 | cls, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | impl From for Axiom { 28 | fn from(dpd: DataPropertyDomain) -> Self { 29 | Axiom::DataPropertyDomain(dpd) 30 | } 31 | } 32 | 33 | #[cfg(feature = "wasm")] 34 | mod wasm { 35 | use wasm_bindgen::prelude::wasm_bindgen; 36 | #[wasm_bindgen(typescript_custom_section)] 37 | const WASM_API: &'static str = r#" 38 | export type DataPropertyDomain = { 39 | dataPropertyIRI: IRI, 40 | cls: ClassConstructor, 41 | annotations: Array, 42 | }; 43 | "#; 44 | } 45 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/data_property_range.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, DataPropertyIRI, DatatypeIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct DataPropertyRange { 5 | #[serde(rename = "dataPropertyIRI")] 6 | pub iri: DataPropertyIRI, 7 | #[serde(rename = "datatypeIRI")] 8 | pub datatype_iri: DatatypeIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl DataPropertyRange { 14 | pub fn new( 15 | data_property_iri: DataPropertyIRI, 16 | datatype_iri: DatatypeIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | iri: data_property_iri, 21 | datatype_iri, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | impl From for Axiom { 28 | fn from(dpr: DataPropertyRange) -> Self { 29 | Axiom::DataPropertyRange(dpr) 30 | } 31 | } 32 | 33 | #[cfg(feature = "wasm")] 34 | mod wasm { 35 | use wasm_bindgen::prelude::wasm_bindgen; 36 | #[wasm_bindgen(typescript_custom_section)] 37 | const WASM_API: &'static str = r#" 38 | export type DataPropertyRange = { 39 | dataPropertyIRI: IRI, 40 | datatypeIRI: IRI, 41 | annotations: Array, 42 | }; 43 | "#; 44 | } 45 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/disjoint_object_properties.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct DisjointObjectProperties { 5 | #[serde(rename = "objectPropertyIRI1")] 6 | pub object_property_iri_1: ObjectPropertyIRI, 7 | #[serde(rename = "objectPropertyIRI2")] 8 | pub object_property_iri_2: ObjectPropertyIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl DisjointObjectProperties { 14 | pub fn new( 15 | object_property_iri_1: ObjectPropertyIRI, 16 | object_property_iri_2: ObjectPropertyIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | object_property_iri_1, 21 | object_property_iri_2, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[cfg(feature = "wasm")] 28 | mod wasm { 29 | use wasm_bindgen::prelude::wasm_bindgen; 30 | 31 | #[wasm_bindgen(typescript_custom_section)] 32 | const WASM_API: &'static str = r#" 33 | export type DisjointObjectProperties = { 34 | objectPropertyIRI1: IRI, 35 | objectPropertyIRI2: IRI, 36 | annotations: Array, 37 | }; 38 | "#; 39 | } 40 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/equivalent_data_properties.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, DataPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct EquivalentDataProperties { 5 | #[serde(rename = "dataPropertyIRI1")] 6 | pub data_property_iri_1: DataPropertyIRI, 7 | #[serde(rename = "dataPropertyIRI2")] 8 | pub data_property_iri_2: DataPropertyIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl EquivalentDataProperties { 14 | pub fn new( 15 | data_property_iri_1: DataPropertyIRI, 16 | data_property_iri_2: DataPropertyIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | data_property_iri_1, 21 | data_property_iri_2, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[cfg(feature = "wasm")] 28 | mod wasm { 29 | use wasm_bindgen::prelude::wasm_bindgen; 30 | #[wasm_bindgen(typescript_custom_section)] 31 | const WASM_API: &'static str = r#" 32 | export type EquivalentDataProperties = { 33 | dataPropertyIRI1: IRI, 34 | dataPropertyIRI2: IRI, 35 | annotations: Array, 36 | }; 37 | "#; 38 | } 39 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/equivalent_object_properties.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct EquivalentObjectProperties { 5 | #[serde(rename = "objectPropertyIRI1")] 6 | pub object_property_iri_1: ObjectPropertyIRI, 7 | #[serde(rename = "objectPropertyIRI2")] 8 | pub object_property_iri_2: ObjectPropertyIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl EquivalentObjectProperties { 14 | pub fn new( 15 | object_property_iri_1: ObjectPropertyIRI, 16 | object_property_iri_2: ObjectPropertyIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | object_property_iri_1, 21 | object_property_iri_2, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[cfg(feature = "wasm")] 28 | mod wasm { 29 | use wasm_bindgen::prelude::wasm_bindgen; 30 | 31 | #[wasm_bindgen(typescript_custom_section)] 32 | const WASM_API: &'static str = r#" 33 | export type EquivalentObjectProperties = { 34 | objectPropertyIRI1: IRI, 35 | objectPropertyIRI2: IRI, 36 | annotations: Array, 37 | }; 38 | "#; 39 | } 40 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/functional_data_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, DataPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct FunctionalDataProperty { 5 | #[serde(rename = "dataPropertyIRI")] 6 | pub data_property_iri: DataPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl FunctionalDataProperty { 12 | pub fn new(data_property_iri: DataPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | data_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | #[cfg(feature = "wasm")] 21 | mod wasm { 22 | use wasm_bindgen::prelude::wasm_bindgen; 23 | 24 | #[wasm_bindgen(typescript_custom_section)] 25 | const WASM_API: &'static str = r#" 26 | export type FunctionalDataProperty = { 27 | dataPropertyIRI: IRI, 28 | annotations: Array, 29 | }; 30 | "#; 31 | } 32 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/functional_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct FunctionalObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl FunctionalObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | #[cfg(feature = "wasm")] 21 | mod wasm { 22 | use wasm_bindgen::prelude::wasm_bindgen; 23 | #[wasm_bindgen(typescript_custom_section)] 24 | const WASM_API: &'static str = r#" 25 | export type FunctionalObjectProperty = { 26 | objectPropertyIRI: IRI, 27 | annotations: Array, 28 | }; 29 | "#; 30 | } 31 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/inverse_functional_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct InverseFunctionalObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl InverseFunctionalObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | #[cfg(feature = "wasm")] 21 | mod wasm { 22 | use wasm_bindgen::prelude::wasm_bindgen; 23 | 24 | #[wasm_bindgen(typescript_custom_section)] 25 | const WASM_API: &'static str = r#" 26 | export type InverseFunctionalObjectProperty = { 27 | objectPropertyIRI: IRI, 28 | annotations: Array, 29 | }; 30 | "#; 31 | } 32 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/inverse_object_properties.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct InverseObjectProperties { 5 | #[serde(rename = "objectPropertyIRI1")] 6 | pub object_property_iri_1: ObjectPropertyIRI, 7 | #[serde(rename = "objectPropertyIRI2")] 8 | pub object_property_iri_2: ObjectPropertyIRI, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl InverseObjectProperties { 14 | pub fn new( 15 | object_property_iri_1: ObjectPropertyIRI, 16 | object_property_iri_2: ObjectPropertyIRI, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | object_property_iri_1, 21 | object_property_iri_2, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | #[cfg(feature = "wasm")] 28 | mod wasm { 29 | use wasm_bindgen::prelude::wasm_bindgen; 30 | #[wasm_bindgen(typescript_custom_section)] 31 | const WASM_API: &'static str = r#" 32 | export type InverseObjectProperties = { 33 | objectPropertyIRI1: IRI, 34 | objectPropertyIRI2: IRI, 35 | annotations: Array, 36 | }; 37 | "#; 38 | } 39 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/irreflexive_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct IrreflexiveObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl IrreflexiveObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | #[cfg(feature = "wasm")] 21 | mod wasm { 22 | use wasm_bindgen::prelude::wasm_bindgen; 23 | #[wasm_bindgen(typescript_custom_section)] 24 | const WASM_API: &'static str = r#" 25 | export type IrreflexiveObjectProperty = { 26 | objectPropertyIRI: IRI, 27 | annotations: Array, 28 | }; 29 | "#; 30 | } 31 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/mod.rs: -------------------------------------------------------------------------------- 1 | mod sub_object_property_of; 2 | pub use sub_object_property_of::*; 3 | 4 | mod sub_annotation_property_of; 5 | pub use sub_annotation_property_of::*; 6 | 7 | mod sub_data_property_of; 8 | pub use sub_data_property_of::*; 9 | 10 | mod equivalent_object_properties; 11 | pub use equivalent_object_properties::*; 12 | 13 | mod disjoint_object_properties; 14 | pub use disjoint_object_properties::*; 15 | 16 | mod object_property_domain; 17 | pub use object_property_domain::*; 18 | 19 | mod object_property_range; 20 | pub use object_property_range::*; 21 | 22 | mod data_property_domain; 23 | pub use data_property_domain::*; 24 | 25 | mod data_property_range; 26 | pub use data_property_range::*; 27 | 28 | mod equivalent_data_properties; 29 | pub use equivalent_data_properties::*; 30 | 31 | mod inverse_object_properties; 32 | pub use inverse_object_properties::*; 33 | 34 | mod symmetric_object_property; 35 | pub use symmetric_object_property::*; 36 | 37 | mod asymmetric_object_property; 38 | pub use asymmetric_object_property::*; 39 | 40 | mod reflexive_object_property; 41 | pub use reflexive_object_property::*; 42 | 43 | mod irreflexive_object_property; 44 | pub use irreflexive_object_property::*; 45 | 46 | mod functional_object_property; 47 | pub use functional_object_property::*; 48 | 49 | mod inverse_functional_object_property; 50 | pub use inverse_functional_object_property::*; 51 | 52 | mod transitive_object_property; 53 | pub use transitive_object_property::*; 54 | 55 | mod functional_data_property; 56 | pub use functional_data_property::*; 57 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/object_property_domain.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ClassConstructor, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectPropertyDomain { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub iri: ObjectPropertyIRI, 7 | #[serde(rename = "cls")] 8 | pub cls: ClassConstructor, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl ObjectPropertyDomain { 14 | pub fn new( 15 | object_property_iri: ObjectPropertyIRI, 16 | cls: ClassConstructor, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | iri: object_property_iri, 21 | cls, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | impl From for Axiom { 28 | fn from(opd: ObjectPropertyDomain) -> Self { 29 | Axiom::ObjectPropertyDomain(opd) 30 | } 31 | } 32 | 33 | #[cfg(feature = "wasm")] 34 | mod wasm { 35 | use wasm_bindgen::prelude::wasm_bindgen; 36 | 37 | #[wasm_bindgen(typescript_custom_section)] 38 | const WASM_API: &'static str = r#" 39 | export type ObjectPropertyDomain = { 40 | objectPropertyIRI: IRI, 41 | cls: ClassConstructor, 42 | annotations: Array, 43 | }; 44 | "#; 45 | } 46 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/object_property_range.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ClassConstructor, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectPropertyRange { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub iri: ObjectPropertyIRI, 7 | #[serde(rename = "cls")] 8 | pub cls: ClassConstructor, 9 | #[serde(rename = "annotations")] 10 | pub annotations: Vec, 11 | } 12 | 13 | impl ObjectPropertyRange { 14 | pub fn new( 15 | object_property_iri: ObjectPropertyIRI, 16 | cls: ClassConstructor, 17 | annotations: Vec, 18 | ) -> Self { 19 | Self { 20 | iri: object_property_iri, 21 | cls, 22 | annotations, 23 | } 24 | } 25 | } 26 | 27 | impl From for Axiom { 28 | fn from(opr: ObjectPropertyRange) -> Self { 29 | Axiom::ObjectPropertyRange(opr) 30 | } 31 | } 32 | 33 | #[cfg(feature = "wasm")] 34 | mod wasm { 35 | use wasm_bindgen::prelude::wasm_bindgen; 36 | #[wasm_bindgen(typescript_custom_section)] 37 | const WASM_API: &'static str = r#" 38 | export type ObjectPropertyRange = { 39 | objectPropertyIRI: IRI, 40 | cls: ClassConstructor, 41 | annotations: Array, 42 | }; 43 | "#; 44 | } 45 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/reflexive_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ReflexiveObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl ReflexiveObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | #[cfg(feature = "wasm")] 21 | mod wasm { 22 | use wasm_bindgen::prelude::wasm_bindgen; 23 | #[wasm_bindgen(typescript_custom_section)] 24 | const WASM_API: &'static str = r#" 25 | export type ReflexiveObjectProperty = { 26 | objectPropertyIRI: IRI, 27 | annotations: Array, 28 | }; 29 | "#; 30 | } 31 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/sub_annotation_property_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, AnnotationPropertyIRI}; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 5 | pub struct SubAnnotationPropertyOf { 6 | #[serde(rename = "annotationPropertyIRI")] 7 | pub subject_iri: AnnotationPropertyIRI, 8 | #[serde(rename = "parentAnnotationPropertyIRI")] 9 | pub parent_iri: AnnotationPropertyIRI, 10 | #[serde(rename = "annotations")] 11 | pub annotations: Vec, 12 | } 13 | 14 | impl SubAnnotationPropertyOf { 15 | pub fn new( 16 | subject_iri: AnnotationPropertyIRI, 17 | parent_iri: AnnotationPropertyIRI, 18 | annotations: Vec, 19 | ) -> Self { 20 | Self { 21 | subject_iri, 22 | parent_iri, 23 | annotations, 24 | } 25 | } 26 | } 27 | 28 | #[cfg(feature = "wasm")] 29 | mod wasm { 30 | use wasm_bindgen::prelude::wasm_bindgen; 31 | 32 | #[wasm_bindgen(typescript_custom_section)] 33 | const WASM_API: &'static str = r#" 34 | export type SubAnnotationProperty = { 35 | annotationPropertyIRI: IRI, 36 | parentAnnotationPropertyIRI: IRI, 37 | annotations: Array, 38 | }; 39 | "#; 40 | } 41 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/sub_data_property_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, DataPropertyIRI}; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 5 | pub struct SubDataPropertyOf { 6 | #[serde(rename = "dataPropertyIRI")] 7 | pub subject_iri: DataPropertyIRI, 8 | #[serde(rename = "parentDataPropertyIRI")] 9 | pub parent_iri: DataPropertyIRI, 10 | #[serde(rename = "annotations")] 11 | pub annotations: Vec, 12 | } 13 | 14 | impl SubDataPropertyOf { 15 | pub fn new( 16 | subject_iri: DataPropertyIRI, 17 | parent_iri: DataPropertyIRI, 18 | annotations: Vec, 19 | ) -> Self { 20 | Self { 21 | subject_iri, 22 | parent_iri, 23 | annotations, 24 | } 25 | } 26 | } 27 | 28 | #[cfg(feature = "wasm")] 29 | mod wasm { 30 | use wasm_bindgen::prelude::wasm_bindgen; 31 | 32 | #[wasm_bindgen(typescript_custom_section)] 33 | const WASM_API: &'static str = r#" 34 | export type SubDataProperty = { 35 | dataPropertyIRI: IRI, 36 | parentDataPropertyIRI: IRI, 37 | annotations: Array, 38 | }; 39 | "#; 40 | } 41 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/sub_object_property_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyConstructor, ObjectPropertyIRI}; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 5 | pub struct SubObjectPropertyOf { 6 | #[serde(rename = "objectProperty")] 7 | pub object_property: ObjectPropertyConstructor, 8 | #[serde(rename = "parentObjectPropertyIRI")] 9 | pub parent_object_property_iri: ObjectPropertyIRI, 10 | #[serde(rename = "annotations")] 11 | pub annotations: Vec, 12 | } 13 | 14 | impl SubObjectPropertyOf { 15 | pub fn new( 16 | object_property: ObjectPropertyConstructor, 17 | parent_object_property_iri: ObjectPropertyIRI, 18 | annotations: Vec, 19 | ) -> Self { 20 | Self { 21 | object_property, 22 | parent_object_property_iri, 23 | annotations, 24 | } 25 | } 26 | } 27 | 28 | #[cfg(feature = "wasm")] 29 | mod wasm { 30 | use wasm_bindgen::prelude::wasm_bindgen; 31 | 32 | #[wasm_bindgen(typescript_custom_section)] 33 | const WASM_API: &'static str = r#" 34 | export type SubObjectPropertyOf = { 35 | objectProperty: ObjectPropertyConstructor, 36 | parentObjectPropertyIRI: IRI, 37 | annotations: Array, 38 | }; 39 | "#; 40 | } 41 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/symmetric_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, Axiom, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct SymmetricObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl SymmetricObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | impl From for Axiom { 21 | fn from(sop: SymmetricObjectProperty) -> Self { 22 | Self::SymmetricObjectProperty(sop) 23 | } 24 | } 25 | 26 | #[cfg(feature = "wasm")] 27 | mod wasm { 28 | use wasm_bindgen::prelude::wasm_bindgen; 29 | #[wasm_bindgen(typescript_custom_section)] 30 | const WASM_API: &'static str = r#" 31 | export type SymmetricObjectProperty = { 32 | objectPropertyIRI: IRI, 33 | annotations: Array, 34 | }; 35 | "#; 36 | } 37 | -------------------------------------------------------------------------------- /src/owl/properties/axioms/transitive_object_property.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{Annotation, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct TransitiveObjectProperty { 5 | #[serde(rename = "objectPropertyIRI")] 6 | pub object_property_iri: ObjectPropertyIRI, 7 | #[serde(rename = "annotations")] 8 | pub annotations: Vec, 9 | } 10 | 11 | impl TransitiveObjectProperty { 12 | pub fn new(object_property_iri: ObjectPropertyIRI, annotations: Vec) -> Self { 13 | Self { 14 | object_property_iri, 15 | annotations, 16 | } 17 | } 18 | } 19 | 20 | #[cfg(feature = "wasm")] 21 | mod wasm { 22 | use wasm_bindgen::prelude::wasm_bindgen; 23 | 24 | #[wasm_bindgen(typescript_custom_section)] 25 | const WASM_API: &'static str = r#" 26 | export type TransitiveObjectProperty = { 27 | objectPropertyIRI: IRI, 28 | annotations: Array, 29 | }; 30 | "#; 31 | } 32 | -------------------------------------------------------------------------------- /src/owl/properties/constructors/mod.rs: -------------------------------------------------------------------------------- 1 | mod object_inverse_of; 2 | pub use object_inverse_of::*; 3 | 4 | mod object_property_chain; 5 | pub use object_property_chain::*; 6 | -------------------------------------------------------------------------------- /src/owl/properties/constructors/object_inverse_of.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{ObjectPropertyConstructor, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectInverseOf(pub ObjectPropertyIRI); 5 | 6 | impl From for ObjectPropertyConstructor { 7 | fn from(c: ObjectInverseOf) -> Self { 8 | Self::ObjectInverseOf(c) 9 | } 10 | } 11 | 12 | #[cfg(feature = "wasm")] 13 | mod wasm { 14 | use wasm_bindgen::prelude::wasm_bindgen; 15 | #[wasm_bindgen(typescript_custom_section)] 16 | const WASM_API: &'static str = r#" 17 | export type ObjectInverseOf = IRI 18 | "#; 19 | } 20 | -------------------------------------------------------------------------------- /src/owl/properties/constructors/object_property_chain.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{ObjectPropertyConstructor, ObjectPropertyIRI}; 2 | 3 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 4 | pub struct ObjectPropertyChain(pub Vec); 5 | 6 | impl From for ObjectPropertyConstructor { 7 | fn from(c: ObjectPropertyChain) -> Self { 8 | Self::ObjectPropertyChain(c) 9 | } 10 | } 11 | 12 | #[cfg(feature = "wasm")] 13 | mod wasm { 14 | use wasm_bindgen::prelude::wasm_bindgen; 15 | #[wasm_bindgen(typescript_custom_section)] 16 | const WASM_API: &'static str = r#" 17 | export type ObjectPropertyChain = Array 18 | "#; 19 | } 20 | -------------------------------------------------------------------------------- /src/owl/properties/mod.rs: -------------------------------------------------------------------------------- 1 | mod axioms; 2 | pub use axioms::*; 3 | 4 | mod constructors; 5 | pub use constructors::*; 6 | 7 | mod annotation_property; 8 | pub use annotation_property::*; 9 | 10 | mod object_properties; 11 | pub use object_properties::*; 12 | use serde::{Deserialize, Serialize}; 13 | 14 | mod annotation; 15 | pub use annotation::*; 16 | 17 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 18 | pub enum ObjectPropertyConstructor { 19 | IRI(ObjectPropertyIRI), 20 | ObjectInverseOf(ObjectInverseOf), 21 | ObjectPropertyChain(ObjectPropertyChain), 22 | } 23 | 24 | #[cfg(feature = "wasm")] 25 | mod wasm { 26 | use wasm_bindgen::prelude::wasm_bindgen; 27 | 28 | #[wasm_bindgen(typescript_custom_section)] 29 | const WASM_API: &'static str = r#" 30 | export interface ObjectPropertyConstructor { 31 | /** 32 | * ObjectProperty IRI 33 | */ 34 | IRI?: IRI 35 | ObjectInverseOf?: ObjectInverseOf 36 | ObjectPropertyChain?: ObjectPropertyChain 37 | } 38 | "#; 39 | } 40 | -------------------------------------------------------------------------------- /src/owl/properties/object_properties.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use crate::{ 4 | error::Error, 5 | owl::{Axiom, IRIList, IndividualIRI, ObjectPropertyConstructor, IRI}, 6 | }; 7 | use crate::owl::ResourceId; 8 | 9 | use super::Annotation; 10 | 11 | #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)] 12 | pub struct ObjectPropertyIRI(IRI); 13 | 14 | impl From for ObjectPropertyIRI { 15 | fn from(iri: IRI) -> Self { 16 | Self(iri) 17 | } 18 | } 19 | impl From for ObjectPropertyConstructor { 20 | fn from(iri: ObjectPropertyIRI) -> Self { 21 | Self::IRI(iri) 22 | } 23 | } 24 | impl TryFrom<&str> for ObjectPropertyIRI { 25 | type Error = Error; 26 | 27 | fn try_from(value: &str) -> Result { 28 | IRI::try_from(value).map(|iri| iri.into()) 29 | } 30 | } 31 | impl ObjectPropertyIRI { 32 | pub fn as_iri(&self) -> &IRI { 33 | &self.0 34 | } 35 | } 36 | 37 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 38 | pub struct ObjectPropertyAssertion { 39 | /// Known IDs of reifications of this assertion. 40 | #[serde(rename = "resourceIds")] 41 | pub resource_ids: Vec, 42 | pub subject: IndividualIRI, 43 | pub iri: ObjectPropertyIRI, 44 | pub object: IRIList, 45 | pub annotations: Vec, 46 | } 47 | 48 | impl ObjectPropertyAssertion { 49 | pub fn new( 50 | iri: ObjectPropertyIRI, 51 | subject: IndividualIRI, 52 | object: IndividualIRI, 53 | annotations: Vec, 54 | resource_ids: Vec, 55 | ) -> Self { 56 | Self { 57 | iri, 58 | subject, 59 | object: IRIList::IRI(object.as_iri().clone()), 60 | annotations, 61 | resource_ids, 62 | } 63 | } 64 | pub fn new_with_list( 65 | iri: ObjectPropertyIRI, 66 | subject: IndividualIRI, 67 | object: Vec, 68 | annotations: Vec, 69 | resource_ids: Vec, 70 | ) -> Self { 71 | Self { 72 | resource_ids, 73 | iri, 74 | subject, 75 | object: IRIList::List(object), 76 | annotations, 77 | } 78 | } 79 | } 80 | 81 | #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] 82 | pub struct NegativeObjectPropertyAssertion { 83 | pub iri: ObjectPropertyIRI, 84 | pub subject: IndividualIRI, 85 | pub object: IndividualIRI, 86 | pub annotations: Vec, 87 | } 88 | 89 | impl NegativeObjectPropertyAssertion { 90 | pub fn new( 91 | iri: ObjectPropertyIRI, 92 | subject: IndividualIRI, 93 | object: IndividualIRI, 94 | annotations: Vec, 95 | ) -> Self { 96 | Self { 97 | iri, 98 | subject, 99 | object, 100 | annotations, 101 | } 102 | } 103 | } 104 | impl From for Axiom { 105 | fn from(opa: ObjectPropertyAssertion) -> Self { 106 | Self::ObjectPropertyAssertion(opa) 107 | } 108 | } 109 | 110 | #[cfg(feature = "wasm")] 111 | mod wasm { 112 | use wasm_bindgen::prelude::wasm_bindgen; 113 | 114 | #[wasm_bindgen(typescript_custom_section)] 115 | const WASM_API1: &'static str = r#" 116 | /** 117 | * Assigngs an ObjectProperty to two Individuals. 118 | */ 119 | export type ObjectPropertyAssertion = { 120 | /** 121 | * The IRI of the property. 122 | */ 123 | iri: IRI, 124 | /** 125 | * The subject Individual. 126 | */ 127 | subject: IRI, 128 | /** 129 | * The object Individual(s). 130 | */ 131 | object: IRIList, 132 | annotations: Array, 133 | }; 134 | "#; 135 | 136 | #[wasm_bindgen(typescript_custom_section)] 137 | const WASM_API2: &'static str = r#" 138 | /** 139 | * Opposite of ObjectPropertyAssertion. 140 | */ 141 | export type NegativeObjectPropertyAssertion = { 142 | /** 143 | * The IRI of the property. 144 | */ 145 | iri: IRI, 146 | /** 147 | * The subject Individual. 148 | */ 149 | subject: IRI, 150 | /** 151 | * The object Individual 152 | */ 153 | object: IRI, 154 | annotations: Array, 155 | }; 156 | "#; 157 | } 158 | -------------------------------------------------------------------------------- /src/owl/well_known.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::{AnnotationPropertyIRI, ClassIRI, DatatypeIRI, IRI}; 2 | 3 | use super::IndividualIRI; 4 | 5 | // Datatypes 6 | #[allow(non_upper_case_globals)] 7 | pub const xsd_base_str: &str = "http://www.w3.org/2001/XMLSchema#"; 8 | 9 | #[allow(non_snake_case)] 10 | pub fn xsd() -> IRI { 11 | IRI::new(xsd_base_str).unwrap() 12 | } 13 | 14 | #[allow(non_upper_case_globals)] 15 | pub const xsd_string_str: &str = "http://www.w3.org/2001/XMLSchema#string"; 16 | 17 | #[allow(non_snake_case)] 18 | pub fn xsd_string() -> DatatypeIRI { 19 | IRI::new(xsd_string_str).unwrap().into() 20 | } 21 | 22 | #[allow(non_upper_case_globals)] 23 | pub const xsd_decimal_str: &str = "http://www.w3.org/2001/XMLSchema#decimal"; 24 | 25 | #[allow(non_snake_case)] 26 | pub fn xsd_decimal() -> DatatypeIRI { 27 | IRI::new(xsd_decimal_str).unwrap().into() 28 | } 29 | 30 | #[allow(non_upper_case_globals)] 31 | pub const xsd_dateTime_str: &str = "http://www.w3.org/2001/XMLSchema#dateTime"; 32 | 33 | #[allow(non_snake_case)] 34 | pub fn xsd_dateTime() -> DatatypeIRI { 35 | IRI::new(xsd_dateTime_str).unwrap().into() 36 | } 37 | 38 | #[allow(non_upper_case_globals)] 39 | pub const xsd_duration_str: &str = "http://www.w3.org/2001/XMLSchema#duration"; 40 | 41 | #[allow(non_snake_case)] 42 | pub fn xsd_duration() -> DatatypeIRI { 43 | IRI::new(xsd_duration_str).unwrap().into() 44 | } 45 | 46 | #[allow(non_upper_case_globals)] 47 | pub const xsd_yearMonthDuration_str: &str = "http://www.w3.org/2001/XMLSchema#yearMonthDuration"; 48 | 49 | #[allow(non_snake_case)] 50 | pub fn xsd_yearMonthDuration() -> DatatypeIRI { 51 | IRI::new(xsd_yearMonthDuration_str).unwrap().into() 52 | } 53 | 54 | #[allow(non_upper_case_globals)] 55 | pub const xsd_dayTimeDuration_str: &str = "http://www.w3.org/2001/XMLSchema#dayTimeDuration"; 56 | 57 | #[allow(non_snake_case)] 58 | pub fn xsd_dayTimeDuration() -> DatatypeIRI { 59 | IRI::new(xsd_dayTimeDuration_str).unwrap().into() 60 | } 61 | 62 | #[allow(non_upper_case_globals)] 63 | pub const xsd_boolean_str: &str = "http://www.w3.org/2001/XMLSchema#boolean"; 64 | 65 | #[allow(non_snake_case)] 66 | pub fn xsd_boolean() -> DatatypeIRI { 67 | IRI::new(xsd_boolean_str).unwrap().into() 68 | } 69 | 70 | #[allow(non_upper_case_globals)] 71 | pub const xsd_integer_str: &str = "http://www.w3.org/2001/XMLSchema#integer"; 72 | 73 | #[allow(non_snake_case)] 74 | pub fn xsd_integer() -> DatatypeIRI { 75 | IRI::new(xsd_integer_str).unwrap().into() 76 | } 77 | 78 | #[allow(non_upper_case_globals)] 79 | pub const xsd_float_str: &str = "http://www.w3.org/2001/XMLSchema#float"; 80 | 81 | #[allow(non_snake_case)] 82 | pub fn xsd_float() -> DatatypeIRI { 83 | IRI::new(xsd_float_str).unwrap().into() 84 | } 85 | 86 | #[allow(non_upper_case_globals)] 87 | pub const xsd_nonNegativeInteger_str: &str = "http://www.w3.org/2001/XMLSchema#nonNegativeInteger"; 88 | 89 | #[allow(non_snake_case)] 90 | pub fn xsd_nonNegativeInteger() -> DatatypeIRI { 91 | IRI::new(xsd_nonNegativeInteger_str).unwrap().into() 92 | } 93 | 94 | #[allow(non_upper_case_globals)] 95 | pub const xsd_minExclusive_str: &str = "http://www.w3.org/2001/XMLSchema#minExclusive"; 96 | 97 | #[allow(non_snake_case)] 98 | pub fn xsd_minExclusive() -> DatatypeIRI { 99 | IRI::new(xsd_minExclusive_str).unwrap().into() 100 | } 101 | 102 | #[allow(non_upper_case_globals)] 103 | pub const xsd_minInclusive_str: &str = "http://www.w3.org/2001/XMLSchema#minInclusive"; 104 | 105 | #[allow(non_snake_case)] 106 | pub fn xsd_minInclusive() -> DatatypeIRI { 107 | IRI::new(xsd_minInclusive_str).unwrap().into() 108 | } 109 | 110 | #[allow(non_upper_case_globals)] 111 | pub const xsd_maxInclusive_str: &str = "http://www.w3.org/2001/XMLSchema#maxInclusive"; 112 | 113 | #[allow(non_snake_case)] 114 | pub fn xsd_maxInclusive() -> DatatypeIRI { 115 | IRI::new(xsd_maxInclusive_str).unwrap().into() 116 | } 117 | 118 | #[allow(non_upper_case_globals)] 119 | pub const xsd_maxExclusive_str: &str = "http://www.w3.org/2001/XMLSchema#maxExclusive"; 120 | 121 | #[allow(non_snake_case)] 122 | pub fn xsd_maxExclusive() -> DatatypeIRI { 123 | IRI::new(xsd_maxExclusive_str).unwrap().into() 124 | } 125 | 126 | // RDFS 127 | #[allow(non_upper_case_globals)] 128 | pub const rdfs_base_str: &str = "http://www.w3.org/2000/01/rdf-schema#"; 129 | #[allow(non_snake_case)] 130 | pub fn rdfs() -> IRI { 131 | IRI::new(rdfs_base_str).unwrap() 132 | } 133 | 134 | #[allow(non_upper_case_globals)] 135 | pub const rdfs_Datatype_str: &str = "http://www.w3.org/2000/01/rdf-schema#Datatype"; 136 | #[allow(non_snake_case)] 137 | pub fn rdfs_Datatype() -> IRI { 138 | IRI::new(rdfs_Datatype_str).unwrap() 139 | } 140 | 141 | #[allow(non_upper_case_globals)] 142 | pub const rdfs_domain_str: &str = "http://www.w3.org/2000/01/rdf-schema#domain"; 143 | #[allow(non_snake_case)] 144 | pub fn rdfs_domain() -> IRI { 145 | IRI::new(rdfs_domain_str).unwrap() 146 | } 147 | 148 | #[allow(non_upper_case_globals)] 149 | pub const rdfs_range_str: &str = "http://www.w3.org/2000/01/rdf-schema#range"; 150 | #[allow(non_snake_case)] 151 | pub fn rdfs_range() -> IRI { 152 | IRI::new(rdfs_range_str).unwrap() 153 | } 154 | 155 | #[allow(non_upper_case_globals)] 156 | pub const rdfs_comment_str: &str = "http://www.w3.org/2000/01/rdf-schema#comment"; 157 | 158 | #[allow(non_snake_case)] 159 | pub fn rdfs_comment() -> AnnotationPropertyIRI { 160 | IRI::new(rdfs_comment_str).unwrap().into() 161 | } 162 | 163 | #[allow(non_upper_case_globals)] 164 | pub const rdfs_label_str: &str = "http://www.w3.org/2000/01/rdf-schema#label"; 165 | 166 | #[allow(non_snake_case)] 167 | pub fn rdfs_label() -> AnnotationPropertyIRI { 168 | IRI::new(rdfs_label_str).unwrap().into() 169 | } 170 | 171 | #[allow(non_upper_case_globals)] 172 | pub const rdfs_subClassOf_str: &str = "http://www.w3.org/2000/01/rdf-schema#subClassOf"; 173 | 174 | #[allow(non_snake_case)] 175 | pub fn rdfs_subClassOf() -> AnnotationPropertyIRI { 176 | IRI::new(rdfs_subClassOf_str).unwrap().into() 177 | } 178 | 179 | // RDF 180 | #[allow(non_upper_case_globals)] 181 | pub const rdf_base_str: &str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 182 | 183 | #[allow(non_snake_case)] 184 | pub fn rdf() -> IRI { 185 | IRI::new(rdf_base_str).unwrap() 186 | } 187 | 188 | #[allow(non_upper_case_globals)] 189 | pub const rdf_first_str: &str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#first"; 190 | #[allow(non_snake_case)] 191 | pub fn rdf_first() -> IRI { 192 | IRI::new(rdf_first_str).unwrap() 193 | } 194 | #[allow(non_upper_case_globals)] 195 | pub const rdf_rest_str: &str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"; 196 | #[allow(non_snake_case)] 197 | pub fn rdf_rest() -> IRI { 198 | IRI::new(rdf_rest_str).unwrap() 199 | } 200 | 201 | #[allow(non_upper_case_globals)] 202 | pub const rdf_type_str: &str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"; 203 | 204 | #[allow(non_snake_case)] 205 | pub fn rdf_type() -> AnnotationPropertyIRI { 206 | IRI::new(rdf_type_str).unwrap().into() 207 | } 208 | 209 | // OWL 210 | #[allow(non_upper_case_globals)] 211 | pub const owl_base_str: &str = "http://www.w3.org/2002/07/owl#"; 212 | 213 | #[allow(non_snake_case)] 214 | pub fn owl() -> IRI { 215 | IRI::new(owl_base_str).unwrap() 216 | } 217 | 218 | #[allow(non_upper_case_globals)] 219 | pub const owl_oneOf_str: &str = "http://www.w3.org/2002/07/owl#oneOf"; 220 | #[allow(non_snake_case)] 221 | pub fn owl_oneOf() -> IRI { 222 | IRI::new(owl_oneOf_str).unwrap() 223 | } 224 | 225 | #[allow(non_upper_case_globals)] 226 | pub const owl_onDatatype_str: &str = "http://www.w3.org/2002/07/owl#onDatatype"; 227 | #[allow(non_snake_case)] 228 | pub fn owl_onDatatype() -> IRI { 229 | IRI::new(owl_onDatatype_str).unwrap() 230 | } 231 | 232 | #[allow(non_upper_case_globals)] 233 | pub const owl_withRestrictions_str: &str = "http://www.w3.org/2002/07/owl#withRestrictions"; 234 | #[allow(non_snake_case)] 235 | pub fn owl_withRestrictions() -> IRI { 236 | IRI::new(owl_withRestrictions_str).unwrap() 237 | } 238 | 239 | #[allow(non_upper_case_globals)] 240 | pub const owl_inverseOf_str: &str = "http://www.w3.org/2002/07/owl#inverseOf"; 241 | #[allow(non_snake_case)] 242 | pub fn owl_inverseOf() -> IRI { 243 | IRI::new(owl_inverseOf_str).unwrap() 244 | } 245 | 246 | #[allow(non_upper_case_globals)] 247 | pub const owl_someValuesFrom_str: &str = "http://www.w3.org/2002/07/owl#someValuesFrom"; 248 | #[allow(non_snake_case)] 249 | pub fn owl_someValuesFrom() -> IRI { 250 | IRI::new(owl_someValuesFrom_str).unwrap() 251 | } 252 | 253 | #[allow(non_upper_case_globals)] 254 | pub const owl_onProperties_str: &str = "http://www.w3.org/2002/07/owl#onProperties"; 255 | #[allow(non_snake_case)] 256 | pub fn owl_onProperties() -> IRI { 257 | IRI::new(owl_onProperties_str).unwrap() 258 | } 259 | 260 | #[allow(non_upper_case_globals)] 261 | pub const owl_onDataRange_str: &str = "http://www.w3.org/2002/07/owl#onDataRange"; 262 | #[allow(non_snake_case)] 263 | pub fn owl_onDataRange() -> IRI { 264 | IRI::new(owl_onDataRange_str).unwrap() 265 | } 266 | 267 | #[allow(non_upper_case_globals)] 268 | pub const owl_allValuesFrom_str: &str = "http://www.w3.org/2002/07/owl#allValuesFrom"; 269 | #[allow(non_snake_case)] 270 | pub fn owl_allValuesFrom() -> IRI { 271 | IRI::new(owl_allValuesFrom_str).unwrap() 272 | } 273 | #[allow(non_upper_case_globals)] 274 | pub const owl_annotatedSource_str: &str = "http://www.w3.org/2002/07/owl#annotatedSource"; 275 | #[allow(non_snake_case)] 276 | pub fn owl_annotatedSource() -> IRI { 277 | IRI::new(owl_annotatedSource_str).unwrap() 278 | } 279 | 280 | #[allow(non_upper_case_globals)] 281 | pub const owl_hasValue_str: &str = "http://www.w3.org/2002/07/owl#hasValue"; 282 | #[allow(non_snake_case)] 283 | pub fn owl_hasValue() -> IRI { 284 | IRI::new(owl_hasValue_str).unwrap() 285 | } 286 | 287 | #[allow(non_upper_case_globals)] 288 | pub const owl_hasSelf_str: &str = "http://www.w3.org/2002/07/owl#hasSelf"; 289 | #[allow(non_snake_case)] 290 | pub fn owl_hasSelf() -> IRI { 291 | IRI::new(owl_hasSelf_str).unwrap() 292 | } 293 | 294 | #[allow(non_upper_case_globals)] 295 | pub const owl_minCardinality_str: &str = "http://www.w3.org/2002/07/owl#minCardinality"; 296 | #[allow(non_snake_case)] 297 | pub fn owl_minCardinality() -> IRI { 298 | IRI::new(owl_minCardinality_str).unwrap() 299 | } 300 | 301 | #[allow(non_upper_case_globals)] 302 | pub const owl_maxCardinality_str: &str = "http://www.w3.org/2002/07/owl#maxCardinality"; 303 | #[allow(non_snake_case)] 304 | pub fn owl_maxCardinality() -> IRI { 305 | IRI::new(owl_maxCardinality_str).unwrap() 306 | } 307 | 308 | #[allow(non_upper_case_globals)] 309 | pub const owl_maxQualifiedCardinality_str: &str = 310 | "http://www.w3.org/2002/07/owl#maxQualifiedCardinality"; 311 | #[allow(non_snake_case)] 312 | pub fn owl_maxQualifiedCardinality() -> IRI { 313 | IRI::new(owl_maxQualifiedCardinality_str).unwrap() 314 | } 315 | 316 | #[allow(non_upper_case_globals)] 317 | pub const owl_minQualifiedCardinality_str: &str = 318 | "http://www.w3.org/2002/07/owl#minQualifiedCardinality"; 319 | #[allow(non_snake_case)] 320 | pub fn owl_minQualifiedCardinality() -> IRI { 321 | IRI::new(owl_minQualifiedCardinality_str).unwrap() 322 | } 323 | 324 | #[allow(non_upper_case_globals)] 325 | pub const owl_cardinality_str: &str = "http://www.w3.org/2002/07/owl#cardinality"; 326 | #[allow(non_snake_case)] 327 | pub fn owl_cardinality() -> IRI { 328 | IRI::new(owl_cardinality_str).unwrap() 329 | } 330 | 331 | #[allow(non_upper_case_globals)] 332 | pub const owl_qualifiedCardinality_str: &str = "http://www.w3.org/2002/07/owl#qualifiedCardinality"; 333 | #[allow(non_snake_case)] 334 | pub fn owl_qualifiedCardinality() -> IRI { 335 | IRI::new(owl_qualifiedCardinality_str).unwrap() 336 | } 337 | 338 | #[allow(non_upper_case_globals)] 339 | pub const owl_onProperty_str: &str = "http://www.w3.org/2002/07/owl#onProperty"; 340 | #[allow(non_snake_case)] 341 | pub fn owl_onProperty() -> IRI { 342 | IRI::new(owl_onProperty_str).unwrap() 343 | } 344 | 345 | #[allow(non_upper_case_globals)] 346 | pub const owl_intersectionOf_str: &str = "http://www.w3.org/2002/07/owl#intersectionOf"; 347 | #[allow(non_snake_case)] 348 | pub fn owl_intersectionOf() -> IRI { 349 | IRI::new(owl_intersectionOf_str).unwrap() 350 | } 351 | 352 | #[allow(non_upper_case_globals)] 353 | pub const owl_unionOf_str: &str = "http://www.w3.org/2002/07/owl#unionOf"; 354 | #[allow(non_snake_case)] 355 | pub fn owl_unionOf() -> IRI { 356 | IRI::new(owl_unionOf_str).unwrap() 357 | } 358 | 359 | #[allow(non_upper_case_globals)] 360 | pub const owl_complementOf_str: &str = "http://www.w3.org/2002/07/owl#complementOf"; 361 | #[allow(non_snake_case)] 362 | pub fn owl_complementOf() -> IRI { 363 | IRI::new(owl_complementOf_str).unwrap() 364 | } 365 | 366 | #[allow(non_upper_case_globals)] 367 | pub const owl_onClass_str: &str = "http://www.w3.org/2002/07/owl#onClass"; 368 | #[allow(non_snake_case)] 369 | pub fn owl_onClass() -> IRI { 370 | IRI::new(owl_onClass_str).unwrap() 371 | } 372 | 373 | #[allow(non_upper_case_globals)] 374 | pub const owl_Ontology_str: &str = "http://www.w3.org/2002/07/owl#Ontology"; 375 | #[allow(non_snake_case)] 376 | pub fn owl_Ontology() -> IRI { 377 | IRI::new(owl_Ontology_str).unwrap() 378 | } 379 | 380 | #[allow(non_upper_case_globals)] 381 | pub const owl_Thing_str: &str = "http://www.w3.org/2002/07/owl#Thing"; 382 | #[allow(non_snake_case)] 383 | pub fn owl_Thing() -> ClassIRI { 384 | IRI::new(owl_Thing_str).unwrap().into() 385 | } 386 | 387 | #[allow(non_upper_case_globals)] 388 | pub const owl_Restriction_str: &str = "http://www.w3.org/2002/07/owl#Restriction"; 389 | #[allow(non_snake_case)] 390 | pub fn owl_Restriction() -> ClassIRI { 391 | IRI::new(owl_Restriction_str).unwrap().into() 392 | } 393 | 394 | #[allow(non_upper_case_globals)] 395 | pub const owl_Class_str: &str = "http://www.w3.org/2002/07/owl#Class"; 396 | #[allow(non_snake_case)] 397 | pub fn owl_Class() -> ClassIRI { 398 | IRI::new(owl_Class_str).unwrap().into() 399 | } 400 | 401 | #[allow(non_upper_case_globals)] 402 | pub const owl_NamedIndividual_str: &str = "http://www.w3.org/2002/07/owl#NamedIndividual"; 403 | #[allow(non_snake_case)] 404 | pub fn owl_NamedIndividual() -> IndividualIRI { 405 | IRI::new(owl_Class_str).unwrap().into() 406 | } 407 | 408 | #[allow(non_upper_case_globals)] 409 | pub const owl_AsymmetricProperty_str: &str = "http://www.w3.org/2002/07/owl#AsymmetricProperty"; 410 | #[allow(non_snake_case)] 411 | pub fn owl_AsymmetricProperty() -> IRI { 412 | IRI::new(owl_AsymmetricProperty_str).unwrap() 413 | } 414 | 415 | #[allow(non_upper_case_globals)] 416 | pub const owl_SymmetricProperty_str: &str = "http://www.w3.org/2002/07/owl#SymmetricProperty"; 417 | #[allow(non_snake_case)] 418 | pub fn owl_SymmetricProperty() -> IRI { 419 | IRI::new(owl_SymmetricProperty_str).unwrap() 420 | } 421 | 422 | #[allow(non_upper_case_globals)] 423 | pub const owl_ObjectProperty_str: &str = "http://www.w3.org/2002/07/owl#ObjectProperty"; 424 | #[allow(non_snake_case)] 425 | pub fn owl_ObjectProperty() -> IRI { 426 | IRI::new(owl_ObjectProperty_str).unwrap() 427 | } 428 | 429 | #[allow(non_upper_case_globals)] 430 | pub const owl_DatatypeProperty_str: &str = "http://www.w3.org/2002/07/owl#DatatypeProperty"; 431 | #[allow(non_snake_case)] 432 | pub fn owl_DatatypeProperty() -> IRI { 433 | IRI::new(owl_DatatypeProperty_str).unwrap() 434 | } 435 | 436 | #[allow(non_upper_case_globals)] 437 | pub const owl_AnnotationProperty_str: &str = "http://www.w3.org/2002/07/owl#AnnotationProperty"; 438 | #[allow(non_snake_case)] 439 | pub fn owl_AnnotationProperty() -> IRI { 440 | IRI::new(owl_AnnotationProperty_str).unwrap() 441 | } 442 | 443 | #[allow(non_upper_case_globals)] 444 | pub const owl_Datatype_str: &str = "http://www.w3.org/2002/07/owl#Datatype"; 445 | #[allow(non_snake_case)] 446 | pub fn owl_Datatype() -> IRI { 447 | IRI::new(owl_Datatype_str).unwrap() 448 | } 449 | 450 | // fno 451 | #[allow(non_upper_case_globals)] 452 | pub const fno_base_str: &str = "https://w3id.org/function/ontology#"; 453 | 454 | #[allow(non_snake_case)] 455 | pub fn fno() -> IRI { 456 | IRI::new(fno_base_str).unwrap() 457 | } 458 | 459 | #[allow(non_upper_case_globals)] 460 | pub const fno_Function_str: &str = "https://w3id.org/function/ontology#Function"; 461 | 462 | #[allow(non_snake_case)] 463 | pub fn fno_Function() -> IRI { 464 | IRI::new(fno_Function_str).unwrap() 465 | } 466 | 467 | #[cfg(test)] 468 | mod test { 469 | 470 | #[test] 471 | fn well_known() { 472 | super::owl_Ontology(); 473 | } 474 | } 475 | -------------------------------------------------------------------------------- /src/parser/annotations.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, convert::TryInto}; 2 | 3 | use crate::owl::{BlankNode, ResourceId}; 4 | use crate::{ 5 | error::Error, 6 | owl::{well_known, Annotation, AnnotationAssertion, LiteralOrIRI, IRI}, 7 | parser::matcher::{RdfMatcher, Value}, 8 | rdf_match, 9 | }; 10 | 11 | use super::{ 12 | collector::{ 13 | get_iri_var, CollectedReification, CollectedReificationKey, MatcherHandler, 14 | OntologyCollector, 15 | }, 16 | matcher::MatcherState, 17 | }; 18 | 19 | const WELL_KNOWN_ANNOTATIONS: [&str; 2] = [ 20 | well_known::rdfs_label_str, 21 | well_known::rdfs_comment_str, 22 | // 23 | ]; 24 | 25 | /// Reification on which further annotations can be stated. 26 | /// 27 | /// https://www.w3.org/TR/2012/REC-owl2-mapping-to-rdf-20121211/#Parsing_of_Annotations 28 | pub(crate) fn match_reifications<'a>( 29 | matchers: &mut Vec<(RdfMatcher, MatcherHandler<'a>)>, 30 | prefixes: &HashMap, 31 | ) -> Result<(), Error> { 32 | // allows for annotations on triples via reification 33 | matchers.push(( 34 | rdf_match!("Reification", prefixes, 35 | [iob:a] [rdf:type] [owl:Axiom] . 36 | [iob:a] [owl:annotatedSource] [:subject] . 37 | [iob:a] [owl:annotatedProperty] [*:predicate] . 38 | [iob:a] [owl:annotatedTarget] [:object] . 39 | )?, 40 | Box::new(|mstate, o, _| { 41 | let Some(reification_id) = mstate.last("a") else { 42 | return Ok(false) 43 | }; 44 | // TODO: adjust to also take blank nodes 45 | let Some(Value::Iri(subject)) = mstate.last("subject") else { 46 | return Ok(false) 47 | }; 48 | let Some(Value::Iri(predicate)) = mstate.last("predicate") else { 49 | return Ok(false) 50 | }; 51 | let Some(raw_object) = mstate.last("object") else { 52 | return Ok(false) 53 | }; 54 | let object = match raw_object { 55 | Value::Iri(object) => object.clone(), 56 | // TODO: Reification should probably take more than just lexical form into account. 57 | Value::Literal { 58 | lexical_form, 59 | datatype_iri: _, 60 | language_tag: _, 61 | } => lexical_form.clone(), 62 | Value::Blank(_) => { 63 | todo!("Blank nodes as annotatedTarget in reification is not supported yet.") 64 | } 65 | }; 66 | let subject: ResourceId = IRI::new(subject)?.into(); 67 | 68 | let collected_reification = CollectedReification { 69 | subject: subject.clone(), 70 | predicate: predicate.clone(), 71 | object: object.clone(), 72 | }; 73 | 74 | let reification_key = match reification_id { 75 | Value::Blank(reification_bn) => CollectedReificationKey::Bn(reification_bn.clone()), 76 | Value::Iri(reification_iri) => { 77 | CollectedReificationKey::Iri(reification_iri.clone()) 78 | } 79 | Value::Literal { .. } => { 80 | unreachable!("Literals can't be reification IDs.") 81 | } 82 | }; 83 | o.insert_reification(reification_key, collected_reification); 84 | 85 | Ok(false) 86 | }), 87 | )); 88 | Ok(()) 89 | } 90 | 91 | /// simple annotation assertions without blank nodes 92 | /// https://www.w3.org/TR/2012/REC-owl2-mapping-to-rdf-20121211/#Parsing_of_Annotations 93 | pub(crate) fn match_simple_annotation_assertions<'a>( 94 | matchers: &mut Vec<(RdfMatcher, MatcherHandler<'a>)>, 95 | _prefixes: &HashMap, 96 | ) -> Result<(), Error> { 97 | matchers.push(( 98 | rdf_match!("AnnotationAssertionSimple", _prefixes, 99 | [iob:subject] [*:predicate] [iol:object] .)?, 100 | Box::new(|mstate, o, options| { 101 | let Some(predicate_iri) = get_iri_var("predicate", mstate)? else { 102 | return Ok(false); 103 | }; 104 | 105 | // Predicate not known as AnnotationProperty 106 | if !(o.annotation_property_declaration(&predicate_iri).is_some() 107 | || options.is_annotation_prop(&predicate_iri) 108 | || WELL_KNOWN_ANNOTATIONS.contains(&predicate_iri.as_str())) 109 | { 110 | return Ok(false); 111 | } 112 | 113 | if let Some(subject) = mstate.get("subject") { 114 | match subject { 115 | Value::Iri(subject_iri) => { 116 | return push_annotation_assertion(IRI::new(subject_iri)?.into(), predicate_iri, mstate, o); 117 | } 118 | Value::Blank(subject_bn) => { 119 | return push_annotation_assertion(BlankNode::from(subject_bn.clone()).into(), predicate_iri, mstate, o); 120 | } 121 | Value::Literal { .. } => unreachable!(), 122 | } 123 | } 124 | 125 | Ok(false) 126 | }), 127 | )); 128 | Ok(()) 129 | } 130 | 131 | /// annotation assertions 132 | /// https://www.w3.org/TR/2012/REC-owl2-mapping-to-rdf-20121211/#Parsing_of_Annotations 133 | pub(crate) fn match_annotation_assertions<'a>( 134 | matchers: &mut Vec<(RdfMatcher, MatcherHandler<'a>)>, 135 | _prefixes: &HashMap, 136 | ) -> Result<(), Error> { 137 | matchers.push(( 138 | rdf_match!("AnnotationAssertion", _prefixes, 139 | [iob:subject] [*:predicate] [iol:object] .)?, 140 | Box::new(|mstate, o, options| { 141 | let Some(subject) = mstate.get("subject") else { 142 | return Ok(false); 143 | }; 144 | let Some(predicate_iri) = get_iri_var("predicate", mstate)? else { 145 | return Ok(false); 146 | }; 147 | let Some(obj) = mstate.get("object") else { 148 | return Ok(false); 149 | }; 150 | 151 | let value: LiteralOrIRI = match obj.clone().try_into() { 152 | Ok(l) => l, 153 | Err(_) => unreachable!(), 154 | }; 155 | 156 | // Predicate not known as AnnotationProperty 157 | if !(o.annotation_property_declaration(&predicate_iri).is_some() 158 | || options.is_annotation_prop(&predicate_iri) 159 | || WELL_KNOWN_ANNOTATIONS.contains(&predicate_iri.as_str())) 160 | { 161 | return Ok(false); 162 | } 163 | 164 | match subject { 165 | Value::Iri(subject_iri) => { 166 | // Here we handle AnnotationAssertions like

where is an iri 167 | // that was previously defined via rdfs:annotatedSource as annotation on 168 | // another OWL axiom. 169 | // Those assertions need to be added to the annotation array of said OWL axiom. 170 | if let Some(annotations) = o.get_used_annotation(subject_iri).cloned() { 171 | for a in annotations { 172 | if let Some(axiom) = o.axiom_mut(a) { 173 | axiom.annotations_mut().push(Annotation::new( 174 | predicate_iri.clone().into(), 175 | value.clone().into(), 176 | vec![], 177 | )) 178 | } 179 | } 180 | } 181 | } 182 | Value::Blank(subject_bn) => { 183 | return handle_annotation_on_bn(o, subject_bn.clone(), predicate_iri, value); 184 | } 185 | Value::Literal { .. } => unreachable!(), 186 | } 187 | 188 | Ok(false) 189 | }), 190 | )); 191 | Ok(()) 192 | } 193 | 194 | fn handle_annotation_on_bn( 195 | o: &mut OntologyCollector, 196 | subject_bn: harriet::triple_production::RdfBlankNode, 197 | predicate_iri: IRI, 198 | value: LiteralOrIRI, 199 | ) -> Result { 200 | let annotate = o 201 | .reification(CollectedReificationKey::Bn(subject_bn.clone())) 202 | .cloned(); 203 | if annotate.is_none() { 204 | return Ok(false); 205 | } 206 | let annotate = annotate.unwrap(); 207 | let subject = annotate.subject; 208 | let predicate = annotate.predicate; 209 | let object = annotate.object; 210 | 211 | // Either apply now, or save for later 212 | if let Some((axiom, _)) = o.get_from_axiom_index_mut(&subject, &predicate, &object) { 213 | axiom 214 | .annotations_mut() 215 | .push(Annotation::new(predicate_iri.into(), value.into(), vec![])) 216 | } else { 217 | o.annotations_for_later 218 | .entry((subject.into(), predicate.into(), object.into())) 219 | .or_insert_with(Vec::new) 220 | .push(Annotation::new(predicate_iri.into(), value.into(), vec![])); 221 | } 222 | 223 | Ok(false) 224 | } 225 | 226 | fn push_annotation_assertion( 227 | subject_resource_id: ResourceId, 228 | predicate_iri: IRI, 229 | mstate: &MatcherState, 230 | o: &mut OntologyCollector, 231 | ) -> Result { 232 | // if let Some(a) = o.reification(CollectedReificationKey::Iri(subject_iri_raw.into())) { 233 | // println!("{:#?}", a); 234 | // } 235 | 236 | // let subject_iri = IRI::new(subject_iri_raw)?; 237 | let Some(object) = mstate.get("object") else { 238 | return Ok(false); 239 | }; 240 | 241 | let object: LiteralOrIRI = match object { 242 | Value::Iri(object_iri) => LiteralOrIRI::IRI(IRI::new(object_iri)?), 243 | Value::Literal { .. } => { 244 | if let Ok(lit) = object.clone().try_into() { 245 | LiteralOrIRI::Literal(lit) 246 | } else { 247 | return Ok(false); 248 | } 249 | } 250 | Value::Blank(_) => todo!(), 251 | }; 252 | 253 | if let Some((axiom, _)) = o.get_from_axiom_index_mut( 254 | &subject_resource_id, 255 | &predicate_iri.to_string(), 256 | &object.to_string(), 257 | ) { 258 | axiom 259 | .annotations_mut() 260 | .push(Annotation::new(predicate_iri.into(), object.into(), vec![])) 261 | } else { 262 | o.push_axiom( 263 | AnnotationAssertion::new(predicate_iri.into(), subject_resource_id, object, vec![], vec![]) 264 | .into(), 265 | ); 266 | } 267 | Ok(true) 268 | } 269 | -------------------------------------------------------------------------------- /src/parser/blank_nodes.rs: -------------------------------------------------------------------------------- 1 | use crate::owl::ClassConstructor; 2 | 3 | use crate::owl::IRI; 4 | 5 | use crate::owl::ObjectIntersectionOf; 6 | use crate::owl::ObjectUnionOf; 7 | use crate::parser::matcher::Value; 8 | 9 | use crate::rdf_match; 10 | 11 | use crate::error::Error; 12 | 13 | use std::collections::HashMap; 14 | 15 | use crate::parser::matcher::RdfMatcher; 16 | 17 | use super::collector::CollectedBlankNode; 18 | use super::collector::MatcherHandler; 19 | 20 | pub(crate) fn match_blank_nodes( 21 | matchers: &mut Vec<(RdfMatcher, MatcherHandler)>, 22 | prefixes: &HashMap, 23 | ) -> Result<(), Error> { 24 | // TODO: parse all kinds of blank nodes to something like `Map`. 25 | 26 | matchers.push(( 27 | rdf_match!("ObjectIntersectionOf", prefixes, 28 | [_:x] [rdf:type] [owl:Class] . 29 | [_:x] [owl:intersectionOf] [:object] . 30 | )?, 31 | Box::new(|mstate, o, _| { 32 | if let Some(Value::Blank(bn)) = mstate.get("x") { 33 | if let Some(Value::Blank(obj)) = mstate.get("object") { 34 | if let Some(seq) = o.get_sequence(obj) { 35 | if seq.iter().all(|v| matches!(v, Value::Iri(_))) { 36 | let mut classes = Vec::new(); 37 | for v in seq { 38 | if let Value::Iri(iri) = v { 39 | let iri = IRI::new(&iri)?; 40 | classes.push(ClassConstructor::IRI(iri.into())); 41 | } 42 | } 43 | o.insert_blank_node( 44 | bn.clone(), 45 | CollectedBlankNode::ClassConstructor(Box::new( 46 | ClassConstructor::ObjectIntersectionOf( 47 | ObjectIntersectionOf::new(classes, vec![]), 48 | ), 49 | )), 50 | ); 51 | return Ok(true); 52 | } else { 53 | todo!("support deeper nested blank nodes") 54 | } 55 | } else { 56 | return Err(Error::new("Could not find referenced sequence".into())); 57 | } 58 | } 59 | } 60 | Ok(false) 61 | }), 62 | )); 63 | 64 | matchers.push(( 65 | rdf_match!("ObjectUnionOf", prefixes, 66 | [_:x] [rdf:type] [owl:Class] . 67 | [_:x] [owl:unionOf] [:object] . 68 | )?, 69 | Box::new(|mstate, o, _| { 70 | if let Some(Value::Blank(bn)) = mstate.get("x") { 71 | if let Some(Value::Blank(obj)) = mstate.get("object") { 72 | if let Some(seq) = o.get_sequence(obj) { 73 | if seq.iter().all(|v| matches!(v, Value::Iri(_))) { 74 | let mut classes = Vec::new(); 75 | for v in seq { 76 | if let Value::Iri(iri) = v { 77 | let iri = IRI::new(&iri)?; 78 | classes.push(ClassConstructor::IRI(iri.into())); 79 | } 80 | } 81 | o.insert_blank_node( 82 | bn.clone(), 83 | CollectedBlankNode::ClassConstructor(Box::new( 84 | ObjectUnionOf::new(classes, vec![]).into(), 85 | )), 86 | ); 87 | return Ok(true); 88 | } else { 89 | todo!("support deeper nested blank nodes") 90 | } 91 | } else { 92 | return Err(Error::new(format!( 93 | "Could not find referenced sequence: {:?}", 94 | bn 95 | ))); 96 | } 97 | } 98 | } 99 | Ok(false) 100 | }), 101 | )); 102 | 103 | Ok(()) 104 | } 105 | -------------------------------------------------------------------------------- /src/parser/data_props.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, convert::TryInto}; 2 | 3 | use crate::{ 4 | error::Error, 5 | owl::{Annotation, DataPropertyAssertion, Literal, IRI}, 6 | parser::matcher::{RdfMatcher, Value}, 7 | rdf_match, 8 | }; 9 | 10 | use super::{ 11 | collector::{get_iri_var, CollectedReificationKey, MatcherHandler, OntologyCollector}, 12 | matcher::MatcherState, 13 | }; 14 | 15 | /// simple dataprop assertions without blank nodes 16 | pub(crate) fn match_simple_dataprop_assertions<'a>( 17 | matchers: &mut Vec<(RdfMatcher, MatcherHandler<'a>)>, 18 | _prefixes: &HashMap, 19 | ) -> Result<(), Error> { 20 | matchers.push(( 21 | rdf_match!("DataPropertyAssertionSimple", _prefixes, 22 | [iob:subject] [*:predicate] [lt:object] .)?, 23 | Box::new(|mstate, o, options| { 24 | if let Some(predicate_iri) = get_iri_var("predicate", mstate)? { 25 | if o.data_property_declaration(&predicate_iri).is_some() 26 | || options.is_data_prop(&predicate_iri) 27 | { 28 | if let Some(subject) = mstate.get("subject") { 29 | match subject { 30 | Value::Iri(subject_iri) => { 31 | return push_dataprop_assertion( 32 | subject_iri, 33 | // value, 34 | predicate_iri, 35 | mstate, 36 | o, 37 | ); 38 | } 39 | Value::Blank(_subject_bn) => {} 40 | Value::Literal { .. } => unreachable!(), 41 | } 42 | } 43 | } 44 | } 45 | 46 | Ok(false) 47 | }), 48 | )); 49 | Ok(()) 50 | } 51 | 52 | /// dataprop assertions 53 | pub(crate) fn match_dataprop_assertions<'a>( 54 | matchers: &mut Vec<(RdfMatcher, MatcherHandler<'a>)>, 55 | _prefixes: &HashMap, 56 | ) -> Result<(), Error> { 57 | matchers.push(( 58 | rdf_match!("DataPropertyAssertion", _prefixes, 59 | [iob:subject] [*:predicate] [lt:object] .)?, 60 | Box::new(|mstate, o, options| { 61 | if let Some(obj) = mstate.get("object") { 62 | let value: Literal = match obj.clone().try_into() { 63 | Ok(l) => l, 64 | Err(_) => unreachable!(), 65 | }; 66 | if let Some(predicate_iri) = get_iri_var("predicate", mstate)? { 67 | if o.data_property_declaration(&predicate_iri).is_some() 68 | || options.is_data_prop(&predicate_iri) 69 | { 70 | if let Some(subject) = mstate.get("subject") { 71 | match subject { 72 | Value::Iri(_subject_iri) => {} 73 | Value::Blank(subject_bn) => { 74 | return handle_dataprop_on_bn( 75 | o, 76 | subject_bn.clone(), 77 | predicate_iri, 78 | value, 79 | ); 80 | } 81 | Value::Literal { .. } => unreachable!(), 82 | } 83 | } 84 | } 85 | } 86 | } 87 | 88 | Ok(false) 89 | }), 90 | )); 91 | Ok(()) 92 | } 93 | 94 | pub(crate) fn handle_dataprop_on_bn( 95 | o: &mut OntologyCollector, 96 | subject_bn: harriet::triple_production::RdfBlankNode, 97 | predicate_iri: IRI, 98 | value: Literal, 99 | ) -> Result { 100 | let annotate = o 101 | .reification(CollectedReificationKey::Bn(subject_bn)) 102 | .cloned(); 103 | if annotate.is_none() { 104 | return Ok(false); 105 | } 106 | let annotate = annotate.unwrap(); 107 | let subject = annotate.subject; 108 | let predicate = annotate.predicate; 109 | let object = annotate.object; 110 | 111 | if let Some((axiom, _)) = o.get_from_axiom_index_mut(&subject, &predicate, &object) { 112 | axiom 113 | .annotations_mut() 114 | .push(Annotation::new(predicate_iri.into(), value.into(), vec![])) 115 | } 116 | 117 | Ok(false) 118 | } 119 | 120 | fn push_dataprop_assertion( 121 | subject_iri: &str, 122 | predicate_iri: IRI, 123 | mstate: &MatcherState, 124 | o: &mut OntologyCollector, 125 | ) -> Result { 126 | let subject_iri = IRI::new(subject_iri)?; 127 | 128 | if o.class_declaration(&subject_iri).is_some() { 129 | return Ok(false); 130 | } 131 | 132 | if let Some(object) = mstate.get("object") { 133 | match object { 134 | Value::Iri(_) => { 135 | return Ok(true); 136 | } 137 | Value::Literal { .. } => { 138 | if let Ok(lit) = object.clone().try_into() { 139 | o.push_axiom( 140 | DataPropertyAssertion::new( 141 | predicate_iri.into(), 142 | subject_iri.into(), 143 | lit, 144 | vec![], 145 | // TODO: ? or will this be handled in push_axiom? 146 | vec![], 147 | ) 148 | .into(), 149 | ); 150 | return Ok(true); 151 | } 152 | return Ok(false); 153 | } 154 | Value::Blank(_) => todo!(), 155 | } 156 | } 157 | Ok(false) 158 | } 159 | -------------------------------------------------------------------------------- /src/parser/declarations.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use crate::{error::Error, owl::Declaration, parser::matcher::RdfMatcher, rdf_match}; 4 | 5 | use super::collector::{get_iri_var, MatcherHandler}; 6 | 7 | /// declarations 8 | /// https://www.w3.org/TR/2012/REC-owl2-mapping-to-rdf-20121211/#Analyzing_Declarations 9 | /// https://www.w3.org/TR/2012/REC-owl2-mapping-to-rdf-20121211/#Parsing_of_Axioms 10 | pub(crate) fn match_declarations( 11 | matchers: &mut Vec<(RdfMatcher, MatcherHandler)>, 12 | prefixes: &HashMap, 13 | ) -> Result<(), Error> { 14 | matchers.push(( 15 | rdf_match!("Ontology", prefixes, [*:subject] [rdf:type] [owl:Ontology] .)?, 16 | Box::new(|mstate, o, _| { 17 | if let Some(iri) = get_iri_var("subject", mstate)? { 18 | o.set_iri(iri); 19 | } 20 | Ok(true) 21 | }), 22 | )); 23 | matchers.push(( 24 | rdf_match!("Class", prefixes, [*:subject] [rdf:type] [owl:Class] .)?, 25 | Box::new(|mstate, o, _| { 26 | if let Some(iri) = get_iri_var("subject", mstate)? { 27 | o.push_declaration(Declaration::Class { 28 | iri: iri.into(), 29 | annotations: vec![], 30 | }); 31 | } 32 | Ok(true) 33 | }), 34 | )); 35 | matchers.push(( 36 | rdf_match!("Datatype",prefixes, [*:subject] [rdf:type] [rdfs:Datatype] .)?, 37 | Box::new(|mstate, o, _| { 38 | if let Some(iri) = get_iri_var("subject", mstate)? { 39 | o.push_declaration(Declaration::Datatype { 40 | iri: iri.into(), 41 | annotations: vec![], 42 | }); 43 | } 44 | Ok(true) 45 | }), 46 | )); 47 | matchers.push(( 48 | rdf_match!("ObjectProperty", prefixes, [*:subject] [rdf:type] [owl:ObjectProperty] .)?, 49 | Box::new(|mstate, o, _| { 50 | if let Some(iri) = get_iri_var("subject", mstate)? { 51 | o.push_declaration(Declaration::ObjectProperty { 52 | iri: iri.into(), 53 | annotations: vec![], 54 | }); 55 | } 56 | Ok(true) 57 | }), 58 | )); 59 | matchers.push(( 60 | rdf_match!("DataProperty", prefixes, [*:subject] [rdf:type] [owl:DatatypeProperty] .)?, 61 | Box::new(|mstate, o, _| { 62 | if let Some(iri) = get_iri_var("subject", mstate)? { 63 | o.push_declaration(Declaration::DataProperty { 64 | iri: iri.into(), 65 | annotations: vec![], 66 | }); 67 | } 68 | Ok(true) 69 | }), 70 | )); 71 | matchers.push(( 72 | rdf_match!("AnnotationProperty", prefixes, [*:subject] [rdf:type] [owl:AnnotationProperty] .)?, 73 | Box::new(|mstate, o, _| { 74 | if let Some(iri) = get_iri_var("subject", mstate)? { 75 | o.push_declaration(Declaration::AnnotationProperty{iri: iri.into(),annotations: vec![],}); 76 | } 77 | Ok(true) 78 | }), 79 | )); 80 | matchers.push(( 81 | rdf_match!("NamedIndividual", prefixes, [*:subject] [rdf:type] [owl:NamedIndividual] .)?, 82 | Box::new(|mstate, o, _| { 83 | if let Some(iri) = get_iri_var("subject", mstate)? { 84 | o.push_declaration(Declaration::NamedIndividual { 85 | iri: iri.into(), 86 | annotations: vec![], 87 | }); 88 | } 89 | Ok(true) 90 | }), 91 | )); 92 | Ok(()) 93 | } 94 | -------------------------------------------------------------------------------- /src/parser/object_property_assertions.rs: -------------------------------------------------------------------------------- 1 | use super::collector::MatcherHandler; 2 | use crate::error::Error; 3 | use crate::get_vars; 4 | use crate::owl::ObjectPropertyAssertion; 5 | use crate::owl::IRI; 6 | use crate::parser::matcher::RdfMatcher; 7 | use crate::parser::matcher::Value; 8 | use crate::rdf_match; 9 | use std::collections::HashMap; 10 | 11 | // const WELL_KNOWN_OBJECT_PROPERTIES: [&str; 2] = [ 12 | // well_known::rdfs_subClassOf_str, 13 | // // 14 | // ]; 15 | 16 | pub(crate) fn push( 17 | matchers: &mut Vec<(RdfMatcher, MatcherHandler)>, 18 | _prefixes: &HashMap, 19 | ) -> Result<(), Error> { 20 | matchers.push(( 21 | rdf_match!("ObjectPropertyAssertion", _prefixes, 22 | // [iri or blank] [iri] [iri or blank] 23 | [+:subject] [*:predicate] [+:object] . 24 | )?, 25 | Box::new(|mstate, o, options| { 26 | let Some(vars) = get_vars!(mstate, subject, predicate, object) else { 27 | return Ok(false); 28 | }; 29 | let Value::Iri(iri) = vars.subject else { 30 | return Ok(false); 31 | }; 32 | let Ok(subject) = IRI::new(iri) else { 33 | return Ok(false); 34 | }; 35 | let Ok(predicate) = vars.predicate.clone().try_into() else { 36 | return Ok(false); 37 | }; 38 | 39 | match vars.object { 40 | Value::Iri(iri) => { 41 | if let Ok(object) = IRI::new(iri) { 42 | if o.object_property_declaration(&predicate).is_some() 43 | || options.is_object_prop(&predicate) 44 | { 45 | o.push_axiom( 46 | ObjectPropertyAssertion::new( 47 | predicate.into(), 48 | subject.into(), 49 | object.into(), 50 | vec![], 51 | vec![] 52 | ) 53 | .into(), 54 | ) 55 | } 56 | } 57 | } 58 | Value::Blank(bn) => { 59 | let mut object = Vec::new(); 60 | let mut b = Some(bn); 61 | while let Some(bn) = b { 62 | b = None; 63 | if let Some(super::collector::CollectedBlankNode::Sequence { 64 | first, 65 | rest, 66 | }) = o.get_blank(bn) 67 | { 68 | if let Some(Value::Iri(iri)) = first { 69 | if let Ok(iri) = IRI::new(iri) { 70 | object.push(iri); 71 | b = rest.as_ref(); 72 | } 73 | } 74 | } 75 | } 76 | if object.len() > 0 { 77 | o.push_axiom( 78 | ObjectPropertyAssertion::new_with_list( 79 | predicate.into(), 80 | subject.into(), 81 | object, 82 | vec![], 83 | vec![], 84 | ) 85 | .into(), 86 | ) 87 | } 88 | } 89 | Value::Literal { .. } => { 90 | unreachable!("Branch should be unreachable, as matcher shouldn't match literal objects.") 91 | } 92 | } 93 | Ok(false) 94 | }), 95 | )); 96 | Ok(()) 97 | } 98 | -------------------------------------------------------------------------------- /src/parser/sequences.rs: -------------------------------------------------------------------------------- 1 | use crate::parser::matcher::Value; 2 | 3 | use crate::rdf_match; 4 | 5 | use std::collections::HashMap; 6 | 7 | use crate::error::Error; 8 | 9 | use super::collector::{CollectedBlankNode, MatcherHandler}; 10 | 11 | use crate::parser::matcher::RdfMatcher; 12 | 13 | pub(crate) fn match_sequences( 14 | matchers: &mut Vec<(RdfMatcher, MatcherHandler)>, 15 | prefixes: &HashMap, 16 | ) -> Result<(), Error> { 17 | matchers.push(( 18 | rdf_match!("sequences_first", prefixes, 19 | [:x] [rdf:first] [:object] . 20 | )?, 21 | Box::new(|mstate, o, _| { 22 | if let Some(Value::Blank(bn)) = mstate.get("x") { 23 | if let Some(object) = mstate.get("object").cloned() { 24 | if o.get_blank(bn).is_some() { 25 | o.update_blank_node_sequence(bn, Some(object), None); 26 | } else { 27 | o.insert_blank_node( 28 | bn.clone(), 29 | CollectedBlankNode::Sequence { 30 | first: Some(object), 31 | rest: None, 32 | }, 33 | ); 34 | } 35 | } 36 | } 37 | Ok(false) 38 | }), 39 | )); 40 | matchers.push(( 41 | rdf_match!("sequences_rest", prefixes, 42 | [:x] [rdf:rest] [:object] . 43 | )?, 44 | Box::new(|mstate, o, _| { 45 | if let Some(Value::Blank(bn)) = mstate.get("x") { 46 | if let Some(Value::Blank(rest)) = mstate.get("object").cloned() { 47 | if o.get_blank(bn).is_some() { 48 | o.update_blank_node_sequence(bn, None, Some(rest)); 49 | } else { 50 | o.insert_blank_node( 51 | bn.clone(), 52 | CollectedBlankNode::Sequence { 53 | first: None, 54 | rest: Some(rest), 55 | }, 56 | ); 57 | } 58 | } 59 | } 60 | Ok(false) 61 | }), 62 | )); 63 | Ok(()) 64 | } 65 | -------------------------------------------------------------------------------- /src/parser/triple.rs: -------------------------------------------------------------------------------- 1 | use harriet::triple_production::{RdfObject, RdfPredicate, RdfSubject, RdfTriple}; 2 | use serde::{Deserialize, Serialize}; 3 | 4 | use crate::owl::{Literal, LiteralOrIRI, IRI}; 5 | 6 | #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] 7 | pub struct Triple { 8 | subject: IRI, 9 | predicate: IRI, 10 | value: LiteralOrIRI, 11 | } 12 | 13 | pub fn parse_triple(ttl: &str) -> Option { 14 | let mut ttl_string = ttl.to_string(); 15 | if !ttl.ends_with('.') { 16 | ttl_string = format!("{} .", ttl) 17 | } 18 | let ttl = harriet::TurtleDocument::parse_full(&ttl_string); 19 | if ttl.is_err() { 20 | eprintln!("{:?}", ttl.unwrap_err()); 21 | return None; 22 | } 23 | let ttl = ttl.unwrap(); 24 | 25 | if let Ok(triples) = harriet::triple_production::TripleProducer::produce_for_document(&ttl) { 26 | if let Some(t) = triples.into_iter().next() { 27 | return Triple::from_rdf(t); 28 | } 29 | } 30 | None 31 | } 32 | 33 | impl Triple { 34 | fn from_rdf(t: RdfTriple<'_>) -> Option { 35 | if let RdfSubject::IRI(sub) = t.subject { 36 | if let Ok(sub) = IRI::new(&sub.iri) { 37 | let RdfPredicate::IRI(pred) = t.predicate; 38 | 39 | if let Ok(pred) = IRI::new(&pred.iri) { 40 | match t.object { 41 | RdfObject::IRI(obj) => { 42 | if let Ok(obj) = IRI::new(&obj.iri) { 43 | return Some(Self { 44 | subject: sub, 45 | predicate: pred, 46 | value: obj.into(), 47 | }); 48 | } 49 | } 50 | RdfObject::Literal(lit) => { 51 | return Some(Self { 52 | subject: sub, 53 | predicate: pred, 54 | value: Literal::from(lit.lexical_form.to_string()).into(), 55 | }); 56 | } 57 | RdfObject::BlankNode(_) => return None, 58 | } 59 | } 60 | } 61 | } 62 | None 63 | } 64 | } 65 | 66 | #[cfg(test)] 67 | mod tests { 68 | use crate::owl::IRI; 69 | 70 | use super::{parse_triple, Triple}; 71 | 72 | #[test] 73 | fn tests() { 74 | let ttl = r#" "1234""#; 75 | let t = parse_triple(ttl); 76 | assert_eq!( 77 | t, 78 | Some(Triple { 79 | subject: IRI::new("http://field33.com/a#1234").unwrap(), 80 | predicate: IRI::new("http://field33.com/ontologies/business_object/Number") 81 | .unwrap(), 82 | value: "1234".into() 83 | }) 84 | ) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | pub fn set_panic_hook() { 2 | // When the `console_error_panic_hook` feature is enabled, we can call the 3 | // `set_panic_hook` function at least once during initialization, and then 4 | // we will get better error messages if our code ever panics. 5 | // 6 | // For more details see 7 | // https://github.com/rustwasm/console_error_panic_hook#readme 8 | #[cfg(feature = "console_error_panic_hook")] 9 | console_error_panic_hook::set_once(); 10 | } 11 | -------------------------------------------------------------------------------- /tests/apqc.rs: -------------------------------------------------------------------------------- 1 | use owlish::api::Ontology; 2 | 3 | #[test] 4 | fn apqc() { 5 | env_logger::try_init().ok(); 6 | let turtle = include_str!("./apqc.ttl"); 7 | 8 | harriet::TurtleDocument::parse_full(turtle) 9 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 10 | .expect("Could not parse with harriet"); 11 | 12 | let o = Ontology::parse(turtle, Default::default()).unwrap(); 13 | 14 | assert_eq!(o.declarations().len(), 174); 15 | assert_eq!(o.axioms().len(), 524); 16 | } 17 | -------------------------------------------------------------------------------- /tests/classes.rs: -------------------------------------------------------------------------------- 1 | use owlish::api::Ontology; 2 | 3 | #[test] 4 | fn classes() { 5 | env_logger::try_init().ok(); 6 | let turtle = include_str!("./classes.ttl"); 7 | 8 | harriet::TurtleDocument::parse_full(turtle) 9 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 10 | .expect("Could not parse with harriet"); 11 | 12 | let o = Ontology::parse(turtle, Default::default()).unwrap(); 13 | 14 | assert_eq!(o.declarations().len(), 226); 15 | assert_eq!(o.axioms().len(), 0); 16 | } 17 | -------------------------------------------------------------------------------- /tests/data_properties.rs: -------------------------------------------------------------------------------- 1 | use owlish::{ 2 | api::Ontology, 3 | owl::{Axiom, DataPropertyAssertion, IRI}, 4 | parser::ParserOptions, 5 | }; 6 | 7 | mod reification; 8 | 9 | #[test] 10 | fn data_properties() { 11 | env_logger::try_init().ok(); 12 | let turtle = include_str!("./data_properties.ttl"); 13 | 14 | harriet::TurtleDocument::parse_full(turtle) 15 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 16 | .expect("Could not parse with harriet"); 17 | 18 | let o = Ontology::parse( 19 | turtle, 20 | ParserOptions::builder() 21 | .known(owlish::owl::Declaration::DataProperty { 22 | iri: IRI::new("http://field33.com/ontologies/test/TestDataProperty") 23 | .unwrap() 24 | .into(), 25 | annotations: vec![], 26 | }) 27 | .build(), 28 | ) 29 | .unwrap(); 30 | // println!("{:#?}", o); 31 | assert_eq!(o.declarations().len(), 2); 32 | assert_eq!(o.axioms().len(), 2); 33 | assert_eq!( 34 | o.axioms()[0], 35 | Axiom::DataPropertyAssertion(DataPropertyAssertion::new( 36 | IRI::new("http://field33.com/ontologies/test/TestDataProperty") 37 | .unwrap() 38 | .into(), 39 | IRI::new("http://field33.com/dataset/test").unwrap().into(), 40 | "29.25".into(), 41 | vec![], 42 | vec![], 43 | )) 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /tests/data_properties.ttl: -------------------------------------------------------------------------------- 1 | . 2 | . 3 | . 4 | . 5 | "29.25" . 6 | -------------------------------------------------------------------------------- /tests/expected.ttl: -------------------------------------------------------------------------------- 1 | @prefix : . 2 | @prefix owl: . 3 | @prefix rdf: . 4 | @prefix xsd: . 5 | @prefix rdfs: . 6 | 7 | rdf:type owl:Ontology . 8 | 9 | ##### Declarations ##### 10 | 11 | :John rdf:type owl:Class . 12 | :Mary rdf:type owl:Class . 13 | :Jim rdf:type owl:Class . 14 | :James rdf:type owl:Class . 15 | :Jack rdf:type owl:Class . 16 | :Bill rdf:type owl:Class . 17 | :Susan rdf:type owl:Class . 18 | :Person rdf:type owl:Class . 19 | :Woman rdf:type owl:Class . 20 | :Parent rdf:type owl:Class . 21 | :Father rdf:type owl:Class . 22 | :Mother rdf:type owl:Class . 23 | :SocialRole rdf:type owl:Class . 24 | :Man rdf:type owl:Class . 25 | :Teenager rdf:type owl:Class . 26 | :ChildlessPerson rdf:type owl:Class . 27 | :Human rdf:type owl:Class . 28 | :Female rdf:type owl:Class . 29 | :HappyPerson rdf:type owl:Class . 30 | :JohnsChildren rdf:type owl:Class . 31 | :NarcisticPerson rdf:type owl:Class . 32 | :Dead rdf:type owl:Class . 33 | :Orphan rdf:type owl:Class . 34 | :Adult rdf:type owl:Class . 35 | :YoungChild rdf:type owl:Class . 36 | :hasWife rdf:type owl:ObjectProperty . 37 | :hasChild rdf:type owl:ObjectProperty . 38 | :hasDaughter rdf:type owl:ObjectProperty . 39 | :loves rdf:type owl:ObjectProperty . 40 | :hasSpouse rdf:type owl:ObjectProperty . 41 | :hasGrandparent rdf:type owl:ObjectProperty . 42 | :hasParent rdf:type owl:ObjectProperty . 43 | :hasBrother rdf:type owl:ObjectProperty . 44 | :hasUncle rdf:type owl:ObjectProperty . 45 | :hasSon rdf:type owl:ObjectProperty . 46 | :hasAncestor rdf:type owl:ObjectProperty . 47 | :hasHusband rdf:type owl:ObjectProperty . 48 | :hasAge rdf:type owl:DatatypeProperty . 49 | :hasSSN rdf:type owl:DatatypeProperty . 50 | :personAge rdf:type owl:Datatype . 51 | :minorAge rdf:type owl:Datatype . 52 | :majorAge rdf:type owl:Datatype . 53 | :toddlerAge rdf:type owl:Datatype . 54 | 55 | ##### DataProperties ##### 56 | 57 | :hasAge rdfs:domain :Person . 58 | :hasAge rdfs:range xsd:nonNegativeInteger . 59 | 60 | ##### ObjectProperties ##### 61 | 62 | :hasWife rdfs:domain :Man . 63 | :hasWife rdfs:range :Woman . 64 | 65 | ##### ClassAssertions ##### 66 | 67 | :Mary rdf:type :Person . 68 | :Mary rdf:type :Woman . 69 | :Jack rdf:type [ 70 | rdf:type owl:Class ; 71 | owl:intersectionOf ( :Person [ 72 | rdf:type owl:Class ; 73 | owl:complementOf :Parent 74 | ]) 75 | ] . 76 | :John rdf:type [ 77 | rdf:type owl:Restriction ; 78 | owl:maxCardinality "4"^^xsd:nonNegativeInteger ; 79 | owl:onProperty :hasChild ; 80 | owl:onClass :Parent 81 | ] . 82 | :john rdf:type [ 83 | rdf:type owl:Restriction ; 84 | owl:minCardinality "2"^^xsd:nonNegativeInteger ; 85 | owl:onProperty :hasChild ; 86 | owl:onClass :Parent 87 | ] . 88 | :john rdf:type [ 89 | rdf:type owl:Restriction ; 90 | owl:cardinality "3"^^xsd:nonNegativeInteger ; 91 | owl:onProperty :hasChild ; 92 | owl:onClass :Parent 93 | ] . 94 | :john rdf:type [ 95 | rdf:type owl:Restriction ; 96 | owl:qualifiedCardinality "5"^^xsd:nonNegativeInteger ; 97 | owl:onProperty :hasChild 98 | ] . 99 | :John rdf:type :Father . 100 | :Father rdf:type :SicialRole . 101 | :Woman rdfs:subClassOf :Person . 102 | :Mother rdfs:subClassOf :Woman . 103 | :Grandfather rdfs:subClassOf [ 104 | rdf:type owl:Class ; 105 | owl:intersectionOf ( :Man :Parent) 106 | ] . 107 | :Teenager rdfs:subClassOf [ 108 | rdf:type owl:Restriction ; 109 | owl:onProperty :hasAge ; 110 | owl:someValuesFrom [ 111 | rdf:type rdfs:Datatype ; 112 | owl:onDatatype xsd:integer ; 113 | owl:withRestrictions ( 114 | [xsd:minExclusive "12"^^xsd:nonNegativeInteger] 115 | [xsd:maxInclusive "19"^^xsd:nonNegativeInteger] 116 | ) 117 | ] 118 | ] . 119 | :Man rdfs:subClassOf :Person . 120 | :Father rdfs:subClassOf [ 121 | rdf:type owl:Class ; 122 | owl:intersectionOf ( :Man :Parent) 123 | ] . 124 | :ChildlessPerson rdfs:subClassOf [ 125 | rdf:type owl:Class ; 126 | owl:intersectionOf ( :Person [ 127 | rdf:type owl:Class ; 128 | owl:complementOf [ 129 | rdf:type owl:Restriction ; 130 | owl:onProperty [ owl:inverseOf :hasParent ] ; 131 | owl:someValuesFrom owl:Thing 132 | ] 133 | ]) 134 | ] . 135 | [ 136 | rdf:type owl:Class ; 137 | owl:intersectionOf ( [ 138 | rdf:type owl:Class ; 139 | owl:oneOf ( :Mary :Bill :Meg) 140 | ] :Female) 141 | ] rdfs:subClassOf [ 142 | rdf:type owl:Class ; 143 | owl:intersectionOf ( :Parent [ 144 | rdf:type owl:Restriction ; 145 | owl:maxQualifiedCardinality "1"^^xsd:nonNegativeInteger ; 146 | owl:onProperty :hasChild 147 | ] [ 148 | rdf:type owl:Class ; 149 | owl:onProperty :hasChild ; 150 | owl:allValuesFrom :Female 151 | ]) 152 | ] . 153 | 154 | ##### AnnotationAssertions ##### 155 | 156 | :Person rdfs:comment "Represents the set of all people" . 157 | 158 | ##### DataPropertyAssertions ##### 159 | 160 | :John :hasAge "51"^^xsd:nonNegativeInteger . 161 | 162 | ##### ObjectPropertyAssertions ##### 163 | 164 | :John :hasWife :Mary . 165 | -------------------------------------------------------------------------------- /tests/large.rs: -------------------------------------------------------------------------------- 1 | use owlish::api::Ontology; 2 | 3 | #[test] 4 | fn large() { 5 | env_logger::try_init().ok(); 6 | let turtle = include_str!("../benches/large.ttl"); 7 | 8 | harriet::TurtleDocument::parse_full(turtle) 9 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 10 | .expect("Could not parse with harriet"); 11 | 12 | let o = Ontology::parse(turtle, Default::default()).unwrap(); 13 | 14 | assert_eq!(o.declarations().len(), 34452); 15 | // TODO: not sure how this "correct number was originally determined 16 | // assert_eq!(o.axioms().len(), 14508); 17 | } 18 | -------------------------------------------------------------------------------- /tests/medium.rs: -------------------------------------------------------------------------------- 1 | use owlish::api::Ontology; 2 | 3 | #[test] 4 | fn medium() { 5 | env_logger::try_init().ok(); 6 | let turtle = include_str!("../benches/medium.ttl"); 7 | 8 | harriet::TurtleDocument::parse_full(turtle) 9 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 10 | .expect("Could not parse with harriet"); 11 | 12 | let o = Ontology::parse(turtle, Default::default()).unwrap(); 13 | 14 | assert_eq!(o.declarations().len(), 1914); 15 | // TODO: not sure how this "correct number was originally determined 16 | // assert_eq!(o.axioms().len(), 806); 17 | } 18 | -------------------------------------------------------------------------------- /tests/object_properties.rs: -------------------------------------------------------------------------------- 1 | use owlish::{ 2 | api::Ontology, 3 | owl::{Axiom, ObjectPropertyDomain, ObjectPropertyRange, IRI}, 4 | parser::ParserOptions, 5 | }; 6 | 7 | #[test] 8 | fn object_properties() { 9 | env_logger::try_init().ok(); 10 | let turtle = include_str!("./object_properties.ttl"); 11 | 12 | harriet::TurtleDocument::parse_full(turtle) 13 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 14 | .expect("Could not parse with harriet"); 15 | 16 | let o = Ontology::parse( 17 | turtle, 18 | ParserOptions::builder() 19 | .known(owlish::owl::Declaration::DataProperty { 20 | iri: IRI::new("http://field33.com/ontologies/test/TestDataProperty") 21 | .unwrap() 22 | .into(), 23 | annotations: vec![], 24 | }) 25 | .build(), 26 | ) 27 | .unwrap(); 28 | assert_eq!(o.declarations().len(), 197); 29 | assert_eq!(o.axioms().len(), 433); 30 | 31 | let mut domain_to_check = None; 32 | let mut range_to_check = None; 33 | for a in o.axioms().iter() { 34 | if let Axiom::ObjectPropertyDomain(d) = &a { 35 | if d.iri 36 | .as_iri() 37 | .as_str() 38 | .ends_with("AccountabilityFulfillingOf") 39 | { 40 | domain_to_check = Some(d) 41 | } 42 | } 43 | if let Axiom::ObjectPropertyRange(r) = &a { 44 | if r.iri 45 | .as_iri() 46 | .as_str() 47 | .ends_with("AccountabilityFulfillingOf") 48 | { 49 | range_to_check = Some(r) 50 | } 51 | } 52 | } 53 | 54 | assert_eq!( 55 | domain_to_check, 56 | Some(&ObjectPropertyDomain::new( 57 | IRI::new( 58 | "http://field33.com/ontologies/EXTERNAL_as_innovation/AccountabilityFulfillingOf" 59 | ) 60 | .unwrap() 61 | .into(), 62 | IRI::new("http://field33.com/ontologies/EXTERNAL_as_innovation/Accountability") 63 | .unwrap() 64 | .into(), 65 | vec![] 66 | )) 67 | ); 68 | 69 | assert_eq!( 70 | range_to_check, 71 | Some(&ObjectPropertyRange::new( 72 | IRI::new( 73 | "http://field33.com/ontologies/EXTERNAL_as_innovation/AccountabilityFulfillingOf" 74 | ) 75 | .unwrap() 76 | .into(), 77 | IRI::new("http://field33.com/ontologies/EXTERNAL_as_innovation/Purpose") 78 | .unwrap() 79 | .into(), 80 | vec![] 81 | )) 82 | ); 83 | } 84 | -------------------------------------------------------------------------------- /tests/small.rs: -------------------------------------------------------------------------------- 1 | use owlish::api::Ontology; 2 | 3 | #[test] 4 | fn small() { 5 | env_logger::try_init().ok(); 6 | let turtle = include_str!("../benches/small.ttl"); 7 | 8 | harriet::TurtleDocument::parse_full(turtle) 9 | .map_err(|e| format!("{}...", &format!("{:?}", e)[..200])) 10 | .expect("Could not parse with harriet"); 11 | 12 | let o = Ontology::parse(turtle, Default::default()).unwrap(); 13 | 14 | assert_eq!(o.declarations().len(), 1000); 15 | assert_eq!(o.axioms().len(), 0); 16 | } 17 | --------------------------------------------------------------------------------