Skip to content

Commit

Permalink
refactor: String slices in favor of Rc strings
Browse files Browse the repository at this point in the history
The Window target ends up creating a new string and it didn't live long enough in any scope so instead we make the targets a bunch of reference counted strings so they can exist longer.
  • Loading branch information
brianp committed Jun 17, 2020
1 parent 1c045a6 commit 0bfad6e
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 65 deletions.
92 changes: 45 additions & 47 deletions load/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,24 @@ pub trait Command {
/// `window_name`: The Name of the first window.
/// `root_path`: The root directory for the tmux session.
#[derive(Debug, Clone)]
pub struct Session<'a> {
pub target: SessionTarget<'a>,
pub struct Session {
pub target: SessionTarget,
pub window_name: Rc<String>,
pub root_path: Option<Rc<PathBuf>>,
}

impl<'a> Session<'a> {
pub fn new(name: &'a str, window_name: Rc<String>, root_path: Option<Rc<PathBuf>>) -> Session<'a> {
impl Session {
pub fn new(name: &str, window_name: Rc<String>, root_path: Option<Rc<PathBuf>>) -> Session {
Session {
target: SessionTarget::new(name),
target: SessionTarget::new(Rc::new(name.to_string())),
window_name,
root_path,
}
}
}

// TODO: Real logic exists here. Test it!
impl<'a> Command for Session<'a> {
impl Command for Session {
fn args(&self) -> Vec<&str> {
let args: Vec<&str> = vec!["new", "-d", "-s", &self.target.arg_string, "-n", &self.window_name];

Expand All @@ -64,30 +64,28 @@ impl<'a> Command for Session<'a> {
/// the mutated value ':' in the SessionTarget. Convert SessionTarget from &str
/// to Rc<String>.
#[derive(Debug, Clone)]
pub struct Window<'a> {
pub session_name: &'a str,
pub struct Window {
pub name: Rc<String>,
pub path: Option<Rc<PathBuf>>,
pub session_name_arg: String,
pub session_target: SessionTarget,
}

impl<'a> Window<'a> {
pub fn new(session_name: &'a str, name: Rc<String>, path: Option<Rc<PathBuf>>) -> Window<'a> {
impl Window {
pub fn new(session_name: &str, name: Rc<String>, path: Option<Rc<PathBuf>>) -> Window {
let mut name_arg: String = String::from(session_name);
name_arg.push(':');

Window {
session_name,
name,
path,
session_name_arg: name_arg,
session_target: SessionTarget::new(Rc::new(name_arg)),
}
}
}

impl<'a> Command for Window<'a> {
impl Command for Window {
fn args(&self) -> Vec<&str> {
let args: Vec<&str> = vec!["new-window", "-t", &self.session_name_arg, "-n", &self.name];
let args: Vec<&str> = vec!["new-window", "-t", &self.session_target.arg_string, "-n", &self.name];

match self.path.as_ref() {
Some(path) => [&args[..], &["-c", path.to_str().unwrap()]].concat(),
Expand Down Expand Up @@ -174,21 +172,21 @@ impl Command for SendKeys {
/// `path`: An `Option<PathBuf>` containing a possible root directory passed to the
/// `-c` arguement.
#[derive(Debug, Clone)]
pub struct Attach<'a> {
pub name: SessionTarget<'a>,
pub struct Attach {
pub name: SessionTarget,
pub root_path: Option<Rc<PathBuf>>,
}

impl<'a> Attach<'a> {
pub fn new(name: &'a str, root_path: Option<Rc<PathBuf>>) -> Attach<'a> {
impl Attach {
pub fn new(name: &str, root_path: Option<Rc<PathBuf>>) -> Attach {
Attach {
name: SessionTarget::new(name),
name: SessionTarget::new(Rc::new(name.to_string())),
root_path,
}
}
}

impl<'a> Command for Attach<'a> {
impl Command for Attach {
fn args(&self) -> Vec<&str> {
let args: Vec<&str> = vec!["attach", "-t", &self.name.arg_string];

Expand Down Expand Up @@ -250,19 +248,19 @@ impl Command for SelectPane {
/// Used to switch to a daemonized session when already within a tmux session.
/// name: The named session to switch to.
#[derive(Debug, Clone)]
pub struct SwitchClient<'a> {
pub name: SessionTarget<'a>,
pub struct SwitchClient {
pub name: SessionTarget,
}

impl<'a> SwitchClient<'a> {
pub fn new(name: &'a str) -> SwitchClient<'a> {
impl SwitchClient {
pub fn new(name: &str) -> SwitchClient {
SwitchClient {
name: SessionTarget::new(name),
name: SessionTarget::new(Rc::new(name.to_string())),
}
}
}

impl<'a> Command for SwitchClient<'a> {
impl Command for SwitchClient {
fn args(&self) -> Vec<&str> {
vec!["switch-client", "-t", &self.name.arg_string]
}
Expand Down Expand Up @@ -307,20 +305,20 @@ impl Command for Pre {
/// containing all the commands that require running in a single Vec. This
/// allows a simple process of first in, first out command execution.
#[derive(Debug, Clone)]
pub enum Commands<'a> {
Attach(Attach<'a>),
pub enum Commands {
Attach(Attach),
Layout(Layout),
Pre(Pre),
SelectPane(SelectPane),
SelectWindow(SelectWindow),
SendKeys(SendKeys),
Session(Session<'a>),
Session(Session),
Split(Split),
SwitchClient(SwitchClient<'a>),
Window(Window<'a>),
SwitchClient(SwitchClient),
Window(Window),
}

impl<'a> Commands<'a> {
impl Commands {
pub fn as_trait(&self) -> &dyn Command {
match self {
Commands::Attach(c) => c,
Expand All @@ -337,62 +335,62 @@ impl<'a> Commands<'a> {
}
}

impl<'a> From<Attach<'a>> for Commands<'a> {
fn from(command: Attach<'a>) -> Self {
impl From<Attach> for Commands {
fn from(command: Attach) -> Self {
Commands::Attach(command)
}
}

impl<'a> From<Layout> for Commands<'a> {
impl From<Layout> for Commands {
fn from(command: Layout) -> Self {
Commands::Layout(command)
}
}

impl<'a> From<Pre> for Commands<'a> {
impl From<Pre> for Commands {
fn from(command: Pre) -> Self {
Commands::Pre(command)
}
}

impl<'a> From<SelectPane> for Commands<'a> {
impl From<SelectPane> for Commands {
fn from(command: SelectPane) -> Self {
Commands::SelectPane(command)
}
}

impl<'a> From<SelectWindow> for Commands<'a> {
impl From<SelectWindow> for Commands {
fn from(command: SelectWindow) -> Self {
Commands::SelectWindow(command)
}
}

impl<'a> From<SendKeys> for Commands<'a> {
impl From<SendKeys> for Commands {
fn from(command: SendKeys) -> Self {
Commands::SendKeys(command)
}
}

impl<'a> From<Session<'a>> for Commands<'a> {
fn from(command: Session<'a>) -> Self {
impl From<Session> for Commands {
fn from(command: Session) -> Self {
Commands::Session(command)
}
}

impl<'a> From<Split> for Commands<'a> {
impl From<Split> for Commands {
fn from(command: Split) -> Self {
Commands::Split(command)
}
}

impl<'a> From<SwitchClient<'a>> for Commands<'a> {
fn from(command: SwitchClient<'a>) -> Self {
impl From<SwitchClient> for Commands {
fn from(command: SwitchClient) -> Self {
Commands::SwitchClient(command)
}
}

impl<'a> From<Window<'a>> for Commands<'a> {
fn from(command: Window<'a>) -> Self {
impl From<Window> for Commands {
fn from(command: Window) -> Self {
Commands::Window(command)
}
}
19 changes: 10 additions & 9 deletions load/src/project/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ pub fn call<'a>(
project_name: &'a str,
daemonize: bool,
tmux_config: &Config,
) -> Result<Vec<Commands<'a>>, String> {
) -> Result<Vec<Commands>, String> {
let mut commands: Vec<Commands> = vec![];
let project_name = Rc::new(project_name);

// There should only be one doc but it's a vec so take the first.
let doc = &yaml_string[0];
Expand Down Expand Up @@ -73,7 +74,7 @@ pub fn call<'a>(
);

let target = WindowTarget::new(
project_name,
Rc::clone(&project_name),
k.as_str().ok_or_else(|| "no target specified")?,
);
commands.append(&mut pane_matcher(
Expand All @@ -93,7 +94,7 @@ pub fn call<'a>(
root.clone()
).into());

let target = WindowTarget::new(project_name, k.as_str().unwrap());
let target = WindowTarget::new(Rc::clone(&project_name), k.as_str().unwrap());
commands.append(&mut common_commands(Target::WindowTarget(target.clone())));

// SendKeys for the exec command
Expand All @@ -115,15 +116,15 @@ pub fn call<'a>(
commands
.push(Window::new(&project_name, Rc::new(s.to_string()), root.clone()).into());

let target = WindowTarget::new(&project_name, &s);
let target = WindowTarget::new(Rc::clone(&project_name), &s);
commands.append(&mut common_commands(Target::WindowTarget(target)));
}
Yaml::Integer(ref s) => {
commands.push(
Window::new(&project_name, Rc::new(format!("{}", s)), root.clone()).into(),
);

let target = WindowTarget::new(&project_name, &s.to_string());
let target = WindowTarget::new(Rc::clone(&project_name), &s.to_string());
commands.append(&mut common_commands(Target::WindowTarget(target)));
}
_ => panic!("Muxed config file formatting isn't recognized."),
Expand All @@ -143,14 +144,14 @@ pub fn call<'a>(
remains.insert(
1,
SendKeys::new(
Target::WindowTarget(WindowTarget::new(&project_name, &w.name)),
Target::WindowTarget(WindowTarget::new(Rc::clone(&project_name), &w.name)),
format!("cd {}", path.display()),
)
.into(),
);
}

remains.push(SelectWindow::new(WindowTarget::new(&project_name, &w.name)).into());
remains.push(SelectWindow::new(WindowTarget::new(Rc::clone(&project_name), &w.name)).into());
remains.push(
SelectPane::new(PaneTarget::new(
&project_name,
Expand Down Expand Up @@ -187,9 +188,9 @@ fn pane_matcher<'a, T>(
common_commands: T,
tmux_config: &Config,
inherited_path: Option<Rc<PathBuf>>,
) -> Result<Vec<Commands<'a>>, String>
) -> Result<Vec<Commands>, String>
where
T: Fn(Target) -> Vec<Commands<'a>>,
T: Fn(Target) -> Vec<Commands>,
{
let mut commands = vec![];
let panes = window["panes"]
Expand Down
19 changes: 10 additions & 9 deletions load/src/tmux/target.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! The structures used to manage commands sent over to tmux.
use std::fmt;
use std::rc::Rc;
use std::usize;

/// A targeted pane for a tmux session
Expand Down Expand Up @@ -38,7 +39,7 @@ pub struct WindowTarget {
}

impl WindowTarget {
pub fn new(session: &str, window: &str) -> WindowTarget {
pub fn new(session: Rc<&str>, window: &str) -> WindowTarget {
WindowTarget {
session: session.to_string(),
window: window.to_string(),
Expand All @@ -55,21 +56,21 @@ impl fmt::Display for WindowTarget {

/// A targeted session for tmux
#[derive(Debug, Clone)]
pub struct SessionTarget<'a> {
pub session: &'a str,
pub arg_string: &'a str,
pub struct SessionTarget {
pub session: Rc<String>,
pub arg_string: Rc<String>,
}

impl<'a> SessionTarget<'a> {
pub fn new(session: &'a str) -> SessionTarget<'a> {
impl SessionTarget {
pub fn new(session: Rc<String>) -> SessionTarget {
SessionTarget {
session,
arg_string: session,
session: Rc::clone(&session),
arg_string: Rc::clone(&session),
}
}
}

impl<'a> fmt::Display for SessionTarget<'a> {
impl fmt::Display for SessionTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.session)
}
Expand Down

0 comments on commit 0bfad6e

Please sign in to comment.