Initial Commit.
This commit is contained in:
227
src/java.rs
Normal file
227
src/java.rs
Normal file
@@ -0,0 +1,227 @@
|
||||
use std::fmt;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::Context;
|
||||
use bytesize::ByteSize;
|
||||
|
||||
pub const JAVA_VM: &str = "java";
|
||||
pub const JAVA_COMPILER: &str = "javac";
|
||||
|
||||
pub const JAVA_EXT_SOURCE: &str = "java";
|
||||
pub const JAVA_EXT_CLASS: &str = "class";
|
||||
|
||||
// TODO: Builder-pattern JVM wrapper.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct JVMBuilder {
|
||||
assertions: bool,
|
||||
monitor: bool,
|
||||
ram_min: Option<ByteSize>,
|
||||
ram_max: Option<ByteSize>,
|
||||
}
|
||||
|
||||
impl JVMBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn assertions(&mut self, assertions: bool) -> &mut Self {
|
||||
self.assertions = assertions;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ram_min(&mut self, ram_min: ByteSize) -> &mut Self {
|
||||
self.ram_min = Some(ram_min);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ram_max(&mut self, ram_max: ByteSize) -> &mut Self {
|
||||
self.ram_max = Some(ram_max);
|
||||
self
|
||||
}
|
||||
|
||||
/// Monitor stdout and stderr in raven's process.
|
||||
pub fn monitor(&mut self, monitor: bool) -> &mut Self {
|
||||
self.monitor = monitor;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(&self) -> JVM {
|
||||
let mut flags = vec![];
|
||||
|
||||
if self.assertions {
|
||||
flags.push(VMFlag::EnableAssert);
|
||||
}
|
||||
|
||||
if let Option::Some(size) = self.ram_min {
|
||||
flags.push(VMFlag::HeapMin { size });
|
||||
}
|
||||
|
||||
if let Option::Some(size) = self.ram_max {
|
||||
flags.push(VMFlag::HeapMax { size });
|
||||
}
|
||||
|
||||
JVM {
|
||||
monitor: self.monitor,
|
||||
flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct JVM {
|
||||
monitor: bool,
|
||||
flags: Vec<VMFlag>,
|
||||
}
|
||||
|
||||
impl JVM {
|
||||
pub fn run<P: AsRef<Path>>(
|
||||
self,
|
||||
entry_point: P,
|
||||
) -> anyhow::Result<(Option<String>, Option<String>)> {
|
||||
let mut cmd = vec![JAVA_VM.to_string()];
|
||||
|
||||
cmd.extend(
|
||||
self.flags
|
||||
.clone()
|
||||
.into_iter()
|
||||
.flat_map(|f| Into::<Vec<String>>::into(f)),
|
||||
);
|
||||
cmd.push(entry_point.as_ref().display().to_string());
|
||||
|
||||
let result = crate::io::run_process(cmd.as_slice());
|
||||
|
||||
if self.monitor
|
||||
&& let Result::Ok((stdout, stderr)) = &result
|
||||
{
|
||||
if let Option::Some(stdout) = stdout
|
||||
&& stdout.len() > 0
|
||||
{
|
||||
print!("{stdout}");
|
||||
}
|
||||
if let Option::Some(stderr) = stderr
|
||||
&& stderr.len() > 0
|
||||
{
|
||||
eprintln!("{stderr}");
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum VMFlag {
|
||||
EnableAssert,
|
||||
HeapMax { size: ByteSize },
|
||||
HeapMin { size: ByteSize },
|
||||
Version,
|
||||
}
|
||||
|
||||
impl Into<Vec<String>> for VMFlag {
|
||||
fn into(self) -> Vec<String> {
|
||||
match self {
|
||||
Self::EnableAssert => vec![String::from("-ea")],
|
||||
Self::HeapMax { size } => vec![format!("Xmx{}", size)],
|
||||
Self::HeapMin { size } => vec![format!("Xms{}", size)],
|
||||
Self::Version => vec![String::from("--version")],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Currently being kept around because it's fine for the current branches,
|
||||
// and is currently serving a to_string() method for the Java version fetch.
|
||||
impl fmt::Display for VMFlag {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"-{}",
|
||||
match self {
|
||||
Self::EnableAssert => String::from("ea"),
|
||||
Self::HeapMax { size } => format!("Xmx{}", size),
|
||||
Self::HeapMin { size } => format!("Xms{}", size),
|
||||
Self::Version => String::from("-version"), // --version
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct CompilerBuilder {
|
||||
class_path: Option<PathBuf>,
|
||||
destination: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl CompilerBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn class_path<S: AsRef<Path>>(&mut self, class_path: S) -> &mut Self {
|
||||
self.class_path = Some(class_path.as_ref().to_path_buf());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn destination<S: AsRef<Path>>(&mut self, destination: S) -> &mut Self {
|
||||
self.destination = Some(destination.as_ref().to_path_buf());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(&self) -> Compiler {
|
||||
let mut flags = vec![];
|
||||
|
||||
if let Option::Some(path) = self.destination.to_owned() {
|
||||
flags.push(CompilerFlag::Destination { path });
|
||||
}
|
||||
|
||||
if let Option::Some(path) = self.class_path.to_owned() {
|
||||
flags.push(CompilerFlag::Classpath { path });
|
||||
}
|
||||
|
||||
Compiler { flags }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Compiler {
|
||||
flags: Vec<CompilerFlag>,
|
||||
}
|
||||
|
||||
impl Compiler {
|
||||
pub fn compile<P: AsRef<Path>>(
|
||||
self,
|
||||
path: P,
|
||||
) -> anyhow::Result<(Option<String>, Option<String>)> {
|
||||
let mut cmd: Vec<String> = vec![JAVA_COMPILER.to_string()];
|
||||
|
||||
cmd.extend(
|
||||
self.flags
|
||||
.clone()
|
||||
.into_iter()
|
||||
.flat_map(|f| Into::<Vec<String>>::into(f)),
|
||||
);
|
||||
cmd.extend(crate::fs::expand_files(path)?.into_iter().filter_map(|f| {
|
||||
Some(
|
||||
f.to_str()
|
||||
.context("Failed to cast PathBuf to &str")
|
||||
.ok()?
|
||||
.to_string(),
|
||||
)
|
||||
}));
|
||||
|
||||
crate::io::run_process(cmd.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CompilerFlag {
|
||||
Destination { path: PathBuf },
|
||||
Classpath { path: PathBuf },
|
||||
}
|
||||
|
||||
impl Into<Vec<String>> for CompilerFlag {
|
||||
fn into(self) -> Vec<String> {
|
||||
match self {
|
||||
Self::Classpath { path } => vec!["-cp".to_string(), path.display().to_string()],
|
||||
Self::Destination { path } => vec!["-d".to_string(), path.display().to_string()],
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user