Implement a rudimentary Keyword struct and the beginnings of ident/entid.
This commit is contained in:
parent
22ebcd65f3
commit
476f04e27b
7 changed files with 144 additions and 0 deletions
|
@ -6,6 +6,9 @@ authors = ["Richard Newman <rnewman@twinql.com>", "Nicholas Alexander <nalexande
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rusqlite = "0.8.0"
|
rusqlite = "0.8.0"
|
||||||
|
|
||||||
|
[dependencies.edn]
|
||||||
|
path = "edn"
|
||||||
|
|
||||||
[dependencies.mentat_query_parser]
|
[dependencies.mentat_query_parser]
|
||||||
path = "query-parser"
|
path = "query-parser"
|
||||||
|
|
||||||
|
|
3
edn/Cargo.toml
Normal file
3
edn/Cargo.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[package]
|
||||||
|
name = "edn"
|
||||||
|
version = "0.0.1"
|
86
edn/src/keyword.rs
Normal file
86
edn/src/keyword.rs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// Copyright 2016 Mozilla
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
// this file except in compliance with the License. You may obtain a copy of the
|
||||||
|
// License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
/// Just like Clojure's Keyword. We'll need this as part of EDN parsing,
|
||||||
|
/// but it's also used for identification within Mentat, so we'll define
|
||||||
|
/// it here first.
|
||||||
|
/// Callers are expected to follow these rules:
|
||||||
|
/// http://www.clojure.org/reference/reader#_symbols
|
||||||
|
#[derive(Clone,Debug,Eq,PartialEq)]
|
||||||
|
pub struct Keyword {
|
||||||
|
pub name: String,
|
||||||
|
pub namespace: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A symbol, optionally with a namespace, that prints with a leading colon.
|
||||||
|
/// This concept is imported from Clojure, as it features in EDN and the query
|
||||||
|
/// syntax that we use.
|
||||||
|
///
|
||||||
|
/// Clojure's constraints are looser than ours, allowing empty namespaces or
|
||||||
|
/// names:
|
||||||
|
///
|
||||||
|
/// ```clojure
|
||||||
|
/// user=> (keyword "" "")
|
||||||
|
/// :/
|
||||||
|
/// user=> (keyword "foo" "")
|
||||||
|
/// :foo/
|
||||||
|
/// user=> (keyword "" "bar")
|
||||||
|
/// :/bar
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// We think that's nonsense, so we only allow keywords like `:bar` and `:foo/bar`,
|
||||||
|
/// with both namespace and main parts containing no whitespace and no colon or slash:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use edn::keyword::Keyword;
|
||||||
|
/// let bar = Keyword::new("bar"); // :bar
|
||||||
|
/// let foo_bar = Keyword::namespaced("foo", "bar"); // :foo/bar
|
||||||
|
/// assert_eq!("bar", bar.name);
|
||||||
|
/// assert_eq!(false, bar.namespace.is_some());
|
||||||
|
/// assert_eq!("bar", foo_bar.name);
|
||||||
|
/// assert_eq!(true, foo_bar.namespace.is_some());
|
||||||
|
/// assert_eq!("foo", foo_bar.namespace.expect("Should have a namespace"));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// If you're not sure whether your input is well-formed, you should use a
|
||||||
|
/// reader function first to validate. TODO: implement `read`.
|
||||||
|
///
|
||||||
|
impl Keyword {
|
||||||
|
pub fn new(name: &str) -> Self {
|
||||||
|
return Keyword { name: name.to_string(), namespace: None };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn namespaced(namespace: &str, name: &str) -> Self {
|
||||||
|
assert!(!name.is_empty(), "Keywords cannot be unnamed.");
|
||||||
|
assert!(!namespace.is_empty(), "Keywords cannot have an empty non-null namespace.");
|
||||||
|
|
||||||
|
// TODO: debug asserts to ensure that neither field matches [ :/].
|
||||||
|
return Keyword { name: name.to_string(), namespace: Some(namespace.to_string()) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToString for Keyword {
|
||||||
|
/// Print the keyword in EDN format.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use edn::keyword::Keyword;
|
||||||
|
/// assert_eq!(":baz", Keyword::new("baz").to_string());
|
||||||
|
/// assert_eq!(":bar/baz", Keyword::namespaced("bar", "baz").to_string());
|
||||||
|
/// ```
|
||||||
|
fn to_string(&self) -> String {
|
||||||
|
// Note that we don't currently do any escaping.
|
||||||
|
if let Some(ref ns) = self.namespace {
|
||||||
|
return format!(":{}/{}", ns, self.name);
|
||||||
|
}
|
||||||
|
return format!(":{}", self.name);
|
||||||
|
}
|
||||||
|
}
|
11
edn/src/lib.rs
Normal file
11
edn/src/lib.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2016 Mozilla
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
// this file except in compliance with the License. You may obtain a copy of the
|
||||||
|
// License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
pub mod keyword;
|
|
@ -1,3 +1,10 @@
|
||||||
[package]
|
[package]
|
||||||
name = "mentat_query_parser"
|
name = "mentat_query_parser"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
[dependencies.edn]
|
||||||
|
path = "../edn"
|
||||||
|
|
||||||
|
[dependencies.mentat_query]
|
||||||
|
path = "../query"
|
||||||
|
|
25
src/ident.rs
Normal file
25
src/ident.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2016 Mozilla
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
// this file except in compliance with the License. You may obtain a copy of the
|
||||||
|
// License at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Unless required by applicable law or agreed to in writing, software distributed
|
||||||
|
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
extern crate edn;
|
||||||
|
|
||||||
|
use edn::keyword::Keyword;
|
||||||
|
|
||||||
|
pub type EntId = u32; // TODO: u64? Not all DB values will be representable in a u32.
|
||||||
|
|
||||||
|
/// The ability to transform entity identifiers (entids) into keyword names (idents).
|
||||||
|
pub trait ToIdent {
|
||||||
|
fn ident(&self, entid: EntId) -> Option<Keyword>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The ability to transform idents into the corresponding entid.
|
||||||
|
pub trait ToEntId {
|
||||||
|
fn entid(&self, ident: &Keyword) -> Option<EntId>;
|
||||||
|
}
|
|
@ -8,11 +8,14 @@
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||||
// specific language governing permissions and limitations under the License.
|
// specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
|
extern crate edn;
|
||||||
extern crate mentat_query_parser;
|
extern crate mentat_query_parser;
|
||||||
extern crate rusqlite;
|
extern crate rusqlite;
|
||||||
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
|
pub mod ident;
|
||||||
|
|
||||||
pub fn get_name() -> String {
|
pub fn get_name() -> String {
|
||||||
return String::from("mentat");
|
return String::from("mentat");
|
||||||
}
|
}
|
||||||
|
@ -30,6 +33,12 @@ pub fn get_connection() -> Connection {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use edn::keyword::Keyword;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_import_edn() {
|
||||||
|
assert_eq!("foo", Keyword::new("foo").name);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_import_parser() {
|
fn can_import_parser() {
|
||||||
|
|
Loading…
Reference in a new issue