Add impl-generator script!
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,9 @@ xcuserdata
|
|||||||
*.mode1v3
|
*.mode1v3
|
||||||
xcshareddata
|
xcshareddata
|
||||||
|
|
||||||
|
# cargo noise
|
||||||
|
target
|
||||||
|
|
||||||
# osx noise
|
# osx noise
|
||||||
.DS_Store
|
.DS_Store
|
||||||
profile
|
profile
|
||||||
|
|||||||
BIN
Contents/Resources/impl-generator-bin
Executable file
BIN
Contents/Resources/impl-generator-bin
Executable file
Binary file not shown.
BIN
Contents/Scripts/Generate Implementation.scpt
Normal file
BIN
Contents/Scripts/Generate Implementation.scpt
Normal file
Binary file not shown.
1
Makefile
1
Makefile
@@ -1,6 +1,7 @@
|
|||||||
all:
|
all:
|
||||||
xcodebuild -configuration Release
|
xcodebuild -configuration Release
|
||||||
cp -r build/Release/Rust.bblm Contents/"Language Modules"
|
cp -r build/Release/Rust.bblm Contents/"Language Modules"
|
||||||
|
cd impl-generator; cargo build --release; cp target/release/impl-generator ../Contents/Resources/impl-generator-bin
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -r build
|
rm -r build
|
||||||
@@ -13,7 +13,9 @@ This is a BBEdit 11 Package for [Rust](http://www.rust-lang.org). It provides th
|
|||||||
- Go to named symbol
|
- Go to named symbol
|
||||||
- Indexed function menu
|
- Indexed function menu
|
||||||
- Code folding
|
- Code folding
|
||||||
- Clippings
|
- Code helpers
|
||||||
|
- Clippings for common code patterns
|
||||||
|
- Autogeneration for standard library trait impls
|
||||||
|
|
||||||
By default, it highlights anything beginning with a capital letter in a certain colour. To turn this off, just change the Identifier colour to be the same as the default text colour in Preferences.
|
By default, it highlights anything beginning with a capital letter in a certain colour. To turn this off, just change the Identifier colour to be the same as the default text colour in Preferences.
|
||||||
|
|
||||||
|
|||||||
43
impl-generator/Cargo.lock
generated
Normal file
43
impl-generator/Cargo.lock
generated
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
[root]
|
||||||
|
name = "impl-generator"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"regex 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "0.1.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memchr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex-syntax 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
7
impl-generator/Cargo.toml
Normal file
7
impl-generator/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "impl-generator"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Ben S <ogham@bsago.me>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
regex = "*"
|
||||||
396
impl-generator/src/main.rs
Normal file
396
impl-generator/src/main.rs
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
extern crate regex;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
use std::process;
|
||||||
|
use std::string::ToString;
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let regex = Regex::new(r##"(?x)
|
||||||
|
^ impl
|
||||||
|
(?: < [^>]+ >)? \s+
|
||||||
|
|
||||||
|
([A-Za-z0-9_:]+)
|
||||||
|
(< [^>]+ >)? \s+
|
||||||
|
|
||||||
|
for \s+
|
||||||
|
|
||||||
|
([A-Za-z0-9_:]+)
|
||||||
|
(< [^>]+ >)? \s*
|
||||||
|
|
||||||
|
\{? $
|
||||||
|
"##).unwrap();
|
||||||
|
|
||||||
|
let stdin = io::stdin();
|
||||||
|
let line = stdin.lock().lines().next().unwrap_or_else(||fail("Failed to read line")).unwrap();
|
||||||
|
|
||||||
|
let caps = regex.captures(&*line).unwrap_or_else(||fail("Invalid impl line"));
|
||||||
|
let trait_name = caps.at(1).unwrap_or("");
|
||||||
|
let trait_args = caps.at(2).unwrap_or("");
|
||||||
|
let type_name = caps.at(3).unwrap_or("");
|
||||||
|
let type_args = caps.at(4).unwrap_or("");
|
||||||
|
|
||||||
|
if let Some(components) = get_components(trait_name) {
|
||||||
|
println!("impl{} {}{} for {}{} {{", type_args, trait_name,trait_args, type_name,type_args);
|
||||||
|
|
||||||
|
let mut printed_anything = false;
|
||||||
|
for component in components.iter() {
|
||||||
|
if printed_anything == false {
|
||||||
|
printed_anything = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
|
||||||
|
let text = component.to_string();
|
||||||
|
|
||||||
|
if text.contains("PARAM") && trait_args.is_empty() {
|
||||||
|
fail(&*format!("Trait {} needs a generic argument", trait_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
let rhs = if trait_args.is_empty() { type_name } else { &trait_args[1 .. trait_args.len() - 1] };
|
||||||
|
|
||||||
|
let text = text.replace("SELF", &*format!("{}{}", type_name, type_args))
|
||||||
|
.replace("PARAM", rhs)
|
||||||
|
.replace("RHS", rhs);
|
||||||
|
|
||||||
|
println!("{}", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("}}");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fail(&*format!("Unknown trait name: {}", trait_name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum Component<'a> {
|
||||||
|
AssocType(&'a str),
|
||||||
|
|
||||||
|
Function {
|
||||||
|
name: &'a str,
|
||||||
|
input: &'a str,
|
||||||
|
output: Option<&'a str>,
|
||||||
|
params: Option<&'a str>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> fmt::Display for Component<'a> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
|
match *self {
|
||||||
|
Component::AssocType(name) => {
|
||||||
|
write!(f, " type {} = <#...#>;", name)
|
||||||
|
},
|
||||||
|
Component::Function { name, input, output, params } => {
|
||||||
|
try!(write!(f, " fn {}", name));
|
||||||
|
|
||||||
|
if let Some(params) = params {
|
||||||
|
try!(write!(f, "<{}>", params));
|
||||||
|
}
|
||||||
|
|
||||||
|
try!(write!(f, "({})", input));
|
||||||
|
|
||||||
|
if let Some(output) = output {
|
||||||
|
try!(write!(f, " -> {}", output));
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, " {{\n <#...#>\n }}")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_components(trait_name: &str) -> Option<Vec<Component<'static>>> {
|
||||||
|
use self::Component::*;
|
||||||
|
|
||||||
|
let bits = match trait_name {
|
||||||
|
|
||||||
|
// -- std::borrow --
|
||||||
|
|
||||||
|
"Borrow" => vec![
|
||||||
|
Function {
|
||||||
|
name: "borrow",
|
||||||
|
input: "&self",
|
||||||
|
output: Some("&PARAM"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"BorrowMut" => vec![
|
||||||
|
Function {
|
||||||
|
name: "borrow_mut",
|
||||||
|
input: "&mut self",
|
||||||
|
output: Some("&mut PARAM"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"IntoCow" => vec![
|
||||||
|
Function {
|
||||||
|
name: "into_cow",
|
||||||
|
input: "self",
|
||||||
|
output: Some("Cow<PARAM>"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"ToOwned" => vec![
|
||||||
|
AssocType("Owned"),
|
||||||
|
Function {
|
||||||
|
name: "to_owned",
|
||||||
|
input: "&self",
|
||||||
|
output: Some("Self::Owned"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::clone --
|
||||||
|
|
||||||
|
"Clone" => vec![
|
||||||
|
Function {
|
||||||
|
name: "clone",
|
||||||
|
input: "&self",
|
||||||
|
output: Some("SELF"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::cmp --
|
||||||
|
|
||||||
|
"PartialEq" => vec![
|
||||||
|
Function {
|
||||||
|
name: "eq",
|
||||||
|
input: "&self, other: &RHS",
|
||||||
|
output: Some("bool"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"PartialOrd" => vec![
|
||||||
|
Function {
|
||||||
|
name: "partial_cmp",
|
||||||
|
input: "&self, other: &RHS",
|
||||||
|
output: Some("Option<Ordering>"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::convert --
|
||||||
|
|
||||||
|
"AsMut" => vec![
|
||||||
|
Function {
|
||||||
|
name: "as_mut",
|
||||||
|
input: "&mut self",
|
||||||
|
output: Some("&mut PARAM"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"AsRef" => vec![
|
||||||
|
Function {
|
||||||
|
name: "as_ref",
|
||||||
|
input: "&self",
|
||||||
|
output: Some("&PARAM"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"From" => vec![
|
||||||
|
Function {
|
||||||
|
name: "from",
|
||||||
|
input: "PARAM",
|
||||||
|
output: Some("SELF"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"Into" => vec![
|
||||||
|
Function {
|
||||||
|
name: "into",
|
||||||
|
input: "self",
|
||||||
|
output: Some("PARAM"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::default --
|
||||||
|
|
||||||
|
"Default" => vec![
|
||||||
|
Function {
|
||||||
|
name: "default",
|
||||||
|
input: "",
|
||||||
|
output: Some("SELF"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::error --
|
||||||
|
|
||||||
|
"Error" => vec![
|
||||||
|
Function {
|
||||||
|
name: "description",
|
||||||
|
input: "&self",
|
||||||
|
output: Some("&str"),
|
||||||
|
params: None,
|
||||||
|
},
|
||||||
|
|
||||||
|
Function {
|
||||||
|
name: "cause",
|
||||||
|
input: "&self",
|
||||||
|
output: Some("Option<&Error>"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::fmt --
|
||||||
|
|
||||||
|
"Binary" | "Debug" | "Display" | "LowerExp" | "LowerHex" | "Octal" |
|
||||||
|
"Pointer" | "UpperExp" | "UpperHex"
|
||||||
|
=> format(),
|
||||||
|
|
||||||
|
// -- std::hash --
|
||||||
|
|
||||||
|
"Hash" => vec![
|
||||||
|
Function {
|
||||||
|
name: "hash",
|
||||||
|
input: "&self, state: &mut H",
|
||||||
|
output: None,
|
||||||
|
params: Some("H: Hasher"),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::iter --
|
||||||
|
|
||||||
|
"Iterator" => vec![
|
||||||
|
AssocType("Item"),
|
||||||
|
Function {
|
||||||
|
name: "next",
|
||||||
|
input: "&mut self",
|
||||||
|
output: Some("Option<Self::Item>"),
|
||||||
|
params: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::ops --
|
||||||
|
|
||||||
|
"Add" => maths("add"),
|
||||||
|
"BitAnd" => maths("bitand"),
|
||||||
|
"BitOr" => maths("bitor"),
|
||||||
|
"BitXor" => maths("bitxor"),
|
||||||
|
"Div" => maths("div"),
|
||||||
|
"Mul" => maths("mul"),
|
||||||
|
"Rem" => maths("rem"),
|
||||||
|
"Shl" => maths("shl"),
|
||||||
|
"Shr" => maths("shr"),
|
||||||
|
"Sub" => maths("sub"),
|
||||||
|
|
||||||
|
"Not" => vec![
|
||||||
|
AssocType("Output"),
|
||||||
|
Function {
|
||||||
|
name: "not",
|
||||||
|
input: "self",
|
||||||
|
output: Some("Self::Output"),
|
||||||
|
params: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"Neg" => vec![
|
||||||
|
AssocType("Output"),
|
||||||
|
Function {
|
||||||
|
name: "neg",
|
||||||
|
input: "self",
|
||||||
|
output: Some("Self::Output"),
|
||||||
|
params: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"Deref" => vec![
|
||||||
|
AssocType("Target"),
|
||||||
|
Function {
|
||||||
|
name: "deref",
|
||||||
|
input: "&'a self",
|
||||||
|
output: Some("&'a Self::Target"),
|
||||||
|
params: Some("'a"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"DerefMut" => vec![
|
||||||
|
AssocType("Target"),
|
||||||
|
Function {
|
||||||
|
name: "deref_mut",
|
||||||
|
input: "&'a mut self",
|
||||||
|
output: Some("&'a mut Self::Target"),
|
||||||
|
params: Some("'a"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"Index" => vec![
|
||||||
|
AssocType("Output"),
|
||||||
|
Function {
|
||||||
|
name: "index",
|
||||||
|
input: "&'a self, index: PARAM",
|
||||||
|
output: Some("&'a Self::Output"),
|
||||||
|
params: Some("'a"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"IndexMut" => vec![
|
||||||
|
AssocType("Output"),
|
||||||
|
Function {
|
||||||
|
name: "index",
|
||||||
|
input: "&'a mut self, index: PARAM",
|
||||||
|
output: Some("&'a mut Self::Output"),
|
||||||
|
params: Some("'a"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// -- std::str --
|
||||||
|
|
||||||
|
"FromStr" => vec![
|
||||||
|
AssocType("Err"),
|
||||||
|
Function {
|
||||||
|
name: "from_str",
|
||||||
|
input: "s: &str",
|
||||||
|
output: Some("Result<SELF, Self::Err>"),
|
||||||
|
params: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maths(name: &'static str) -> Vec<Component<'static>> {
|
||||||
|
vec![
|
||||||
|
Component::AssocType("Output"),
|
||||||
|
Component::Function {
|
||||||
|
name: name,
|
||||||
|
input: "self, rhs: RHS",
|
||||||
|
output: Some("Self::Output"),
|
||||||
|
params: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format() -> Vec<Component<'static>> {
|
||||||
|
vec![
|
||||||
|
Component::Function {
|
||||||
|
name: "fmt",
|
||||||
|
input: "&self, &mut fmt::Formatter",
|
||||||
|
output: Some("Result<(), fmt::Error>"),
|
||||||
|
params: None,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fail(message: &str) -> ! {
|
||||||
|
println!("{}", message);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user