Skip to content

Commit

Permalink
feat: handle errors in extract_alias function with enum
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelarie committed Oct 10, 2024
1 parent a394e88 commit b9fedb8
Showing 1 changed file with 39 additions and 15 deletions.
54 changes: 39 additions & 15 deletions src/syntax_tree/alias.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,57 @@
// Unquote a string (remove the quotes if it has)
// 'foo' -> foo
// "foo" -> foo
// foo -> foo
// "\'foo\'" -> 'foo'
// TODO: Add tests
fn unquote_string(string: &str) -> String {
let has_single_quotes = string.starts_with('\'') && string.ends_with('\'');
let has_double_quotes = string.starts_with('"') && string.ends_with('"');

if has_single_quotes || has_double_quotes {
string[1..string.len() - 1].to_string()
} else {
string.to_string()
}
}

enum AliasError {
MissingCommandName,
MissingAliasName,
MissingArguments,
InvalidArgumentCount,
InvalidUtf8Text,
}

// https://www.gnu.org/software/bash/manual/html_node/Quoting.html
// TODO: Handle each error of this function with a enum (AliasError)
// return: -> Result<(String, String), AliasError> {
fn extract_alias(
node: tree_sitter::Node,
source: &[u8],
) -> Option<(String, String)> {
) -> Result<(String, String), AliasError> {
let mut cursor = node.walk();

// Find the command_name node
if !cursor.goto_first_child() || cursor.node().kind() != "command_name" {
return None;
return Err(AliasError::MissingCommandName);
}

// Check if it's an alias command
let command_name = cursor.node().utf8_text(source).unwrap();
if command_name != "alias" {
return None;
return Err(AliasError::MissingAliasName);
}

// Go to the argument node
if !cursor.goto_next_sibling() {
return None;
return Err(AliasError::MissingArguments);
}

let node = cursor.node();

if node.child_count() != 2 {
return None;
return Err(AliasError::InvalidArgumentCount);
}

cursor.goto_first_child();
Expand All @@ -38,16 +64,14 @@ fn extract_alias(

cursor.goto_next_sibling();

let alias_content_node = cursor.node();
let alias_content = alias_content_node
.utf8_text(source)
.unwrap()
// TODO: Check all the cases for quotting in the Bash reference manual:
// https://www.gnu.org/software/bash/manual/html_node/Quoting.html
// and implement a unquote content fn
.trim_matches('\'');
let alias_content = match cursor.node().utf8_text(source) {
Ok(alias_content) => alias_content,
Err(_) => return Err(AliasError::InvalidUtf8Text),
};

let unquoted_alias_content = unquote_string(alias_content);

Some((alias_name.to_string(), alias_content.to_string()))
Ok((alias_name.to_string(), unquoted_alias_content))
}

pub fn find_aliases(
Expand All @@ -65,7 +89,7 @@ pub fn find_aliases(
let node = cursor.node();

if node.kind() == "command" {
if let Some(alias) = extract_alias(node, source) {
if let Ok(alias) = extract_alias(node, source) {
aliases.push(alias);
}
} // TODO: Implement alias detection inside functions
Expand Down

0 comments on commit b9fedb8

Please sign in to comment.