1#![doc = include_str!("../README.md")]
2
3#[macro_use]
4extern crate thiserror;
5#[macro_use]
6extern crate pest_derive;
7
8extern crate curie;
9extern crate horned_owl;
10#[cfg(feature = "memmap")]
11extern crate memmap;
12extern crate pest;
13
14mod as_ofn;
15mod error;
16mod from_ofn;
17mod from_pair;
18mod parser;
19
20use std::collections::HashMap;
21use std::fmt::Debug;
22use std::fmt::Formatter;
23use std::fmt::Write;
24use std::fs::File;
25use std::io::Read;
26use std::path::Path;
27
28use curie::PrefixMapping;
29use horned_owl::model::Build;
30use horned_owl::model::Ontology;
31use horned_owl::ontology::axiom_mapped::AxiomMappedOntology;
32
33pub use self::as_ofn::AsFunctional;
34pub use self::as_ofn::Functional;
35pub use self::error::Error;
36pub use self::error::Result;
37pub use self::from_ofn::FromFunctional;
38
39#[derive(Default)]
41pub struct Context<'a> {
42 build: Option<&'a Build>,
43 prefixes: Option<&'a PrefixMapping>,
44}
45
46impl<'a> Debug for Context<'a> {
48 fn fmt(&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
49 f.debug_struct("Context")
50 .field("build", &self.build)
51 .field(
52 "prefixes",
53 &match &self.prefixes {
54 None => format!("{}", "None"),
55 Some(p) => {
56 format!("{:?}", p.mappings().collect::<HashMap<_, _>>())
57 }
58 },
59 )
60 .finish()
61 }
62}
63
64impl<'a> Context<'a> {
65 pub fn new<B, P>(build: B, prefixes: P) -> Self
67 where
68 B: Into<Option<&'a Build>>,
69 P: Into<Option<&'a PrefixMapping>>,
70 {
71 Self {
72 build: build.into(),
73 prefixes: prefixes.into(),
74 }
75 }
76
77 pub fn iri<S: Into<String>>(&self, s: S) -> horned_owl::model::IRI
79 where
80 S: AsRef<str>,
81 {
82 match self.build {
83 Some(b) => b.iri(s),
84 None => Build::default().iri(s),
85 }
86 }
87}
88
89impl<'a> From<&'a Build> for Context<'a> {
90 fn from(build: &'a Build) -> Context<'a> {
91 Self {
92 build: Some(build),
93 prefixes: None,
94 }
95 }
96}
97
98impl<'a> From<&'a PrefixMapping> for Context<'a> {
99 fn from(prefixes: &'a PrefixMapping) -> Context<'a> {
100 Self {
101 build: None,
102 prefixes: Some(prefixes),
103 }
104 }
105}
106
107#[inline]
109pub fn from_str<O, S>(src: S) -> Result<(O, PrefixMapping)>
110where
111 O: Ontology + FromFunctional,
112 S: AsRef<str>,
113{
114 FromFunctional::from_ofn(src.as_ref())
115}
116
117#[inline]
119pub fn from_reader<O, R>(mut r: R) -> Result<(O, PrefixMapping)>
120where
121 O: Ontology + FromFunctional,
122 R: Read,
123{
124 let mut s = String::new();
125 r.read_to_string(&mut s)?;
126 from_str(s)
127}
128
129#[inline]
131pub fn from_file<O, P>(path: P) -> Result<(O, PrefixMapping)>
132where
133 O: Ontology + FromFunctional,
134 P: AsRef<Path>,
135{
136 let f = File::open(path)?; #[cfg(not(feature = "memmap"))]
138 return from_reader(f);
139
140 #[cfg(feature = "memmap")]
141 unsafe {
142 let map = memmap::Mmap::map(&f)?;
143 match std::str::from_utf8(&map) {
144 Ok(text) => from_str(text),
145 Err(error) => Err(Error::IO(std::io::Error::new(
146 std::io::ErrorKind::InvalidData,
147 error,
148 ))),
149 }
150 }
151}
152
153#[inline]
155pub fn to_string<'a, P>(ontology: &AxiomMappedOntology, prefixes: P) -> String
156where
157 P: Into<Option<&'a PrefixMapping>>,
158{
159 let mut dest = String::new();
160 let p = prefixes.into();
162 if let Some(pm) = p {
163 write!(dest, "{}", pm.as_ofn()).expect("infallible");
164 }
165 let ctx = Context::new(None, p);
167 write!(dest, "{}", ontology.as_ofn_ctx(&ctx)).expect("infallible");
168 dest
170}