Skip to content

Instantly share code, notes, and snippets.

@jfhbrook
Created July 1, 2022 01:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfhbrook/f55684d770d04a62e1367d8091509f53 to your computer and use it in GitHub Desktop.
Save jfhbrook/f55684d770d04a62e1367d8091509f53 to your computer and use it in GitHub Desktop.
use std::os::unix::net::UnixStream;
use std::net::Shutdown;
use std::io::{BufRead, BufReader,BufWriter, Write};
use std::thread;
use anyhow::{Result, Error};
use clap::{Parser, Subcommand};
// use miette::{Diagnostic, SourceSpan};
// use thiserror::Error;
use rustyline::error::ReadlineError;
use rustyline::Editor;
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
#[clap(subcommand)]
command: CliCommand
}
#[derive(Subcommand, Debug)]
enum CliCommand {
Console,
Command {
command: String
}
}
// TODO: clap infrastructure
// TODO: find the socket lol
// TODO: create unix stream
// TODO: rustyline hiworld
//
struct Server<'a> {
// reader: BufReader<&'a UnixStream>,
writer: BufWriter<&'a UnixStream>,
handle: thread::JoinHandle<Result<(), Error>>
}
impl<'a> Server<'a> {
fn new(socket: &'a UnixStream) -> Result<Server<'a>, Error> {
let reader = BufReader::new(socket);
let writer = BufWriter::new(socket);
let handle = thread::spawn(move || -> Result<(), Error> {
let mut line = String::new();
loop {
let len = reader.read_line(&mut line)?;
println!("line is {len} bytes long");
println!("line is: {line}");
}
});
Ok(Server {
// reader,
writer,
handle
})
}
fn send(&mut self, command: &String) -> Result<(), Error> {
// TODO: I should be able to concat these but rust makes it way
// harder than it should be
self.writer.write(b"<command>")?;
self.writer.write(command.as_bytes())?;
self.writer.write(b"</command>")?;
self.writer.write(b"\n")?;
Ok(())
}
}
fn find_socket() -> String {
// TODO: find this automatically
String::from("/tmp/openmsx-josh/socket.820434")
}
fn main() -> Result<(), Error> {
let cli = Args::parse();
let socket = UnixStream::connect(find_socket())?;
let mut server = Server::new(&socket)?;
match &cli.command {
CliCommand::Console => {
let mut rl = Editor::<()>::new();
if rl.load_history(".omsxctl_history").is_err() {
println!("no previous history");
}
loop {
let readline = rl.readline("openmsx> ");
match readline {
Ok(line) => {
rl.add_history_entry(line.as_str());
server.send(&line)?;
},
Err(ReadlineError::Interrupted) => {
println!("CTRL-C");
break
},
Err(ReadlineError::Eof) => {
println!("CTRL-D");
break
},
Err(err) => {
println!("Error: {:?}", err);
break
}
}
}
},
CliCommand::Command { command } => {
server.send(&command)?;
}
}
socket.shutdown(Shutdown::Both)?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment