Skip to content

Commit

Permalink
feat: draft for parsing rockspec
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcjkb committed Jan 21, 2024
1 parent 23e6ce8 commit 9fb1545
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rocks-lib/src/rocks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod download;
mod rockspec;

pub use download::*;
pub use rockspec::*;
207 changes: 207 additions & 0 deletions rocks-lib/src/rocks/rockspec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
use eyre::{eyre, Result};
use mlua::{Lua, LuaSerdeExt, Value};
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Rockspec {
/// The file format version. Example: "1.0"
pub rockspec_format: Option<String>,
/// The name of the package. Example: "LuaSocket"
pub package: String,
/// The version of the package, plus a suffix indicating the revision of the rockspec. Example: "2.0.1-1"
pub version: String,
pub description: RockDescription,
}

impl Rockspec {
pub fn new(rockspec_content: &String) -> Result<Self> {
let lua = Lua::new();
lua.load(rockspec_content).exec()?;

let rockspec = Rockspec {
rockspec_format: lua.from_value(lua.globals().get("rockspec_format")?)?,
package: lua.from_value(lua.globals().get("package")?)?,
version: lua.from_value(lua.globals().get("version")?)?,
description: RockDescription::from_lua(&lua)?,
};

Ok(rockspec)
}
}

#[derive(Deserialize, Debug, PartialEq, Default)]
pub struct RockDescription {
/// A one-line description of the package.
pub summary: Option<String>,
/// A longer description of the package.
pub detailed: Option<String>,
/// The license used by the package.
pub license: Option<String>,
/// An URL for the project. This is not the URL for the tarball, but the address of a website.
pub homepage: Option<String>,
/// An URL for the project's issue tracker.
pub issues_url: Option<String>,
/// Contact information for the rockspec maintainer.
pub maintainer: Option<String>,
/// A list of short strings that specify labels for categorization of this rock.
pub labels: Vec<String>,
}

impl RockDescription {
fn from_lua(lua: &Lua) -> Result<RockDescription> {
match lua.globals().get("description")? {
Value::Nil => Ok(RockDescription::default()),
Value::Table(tbl) => {
let labels = if tbl.contains_key("labels")? {
lua.from_value(tbl.get("labels")?)?
} else {
Vec::new()
};
Ok(RockDescription {
summary: lua.from_value(tbl.get("summary")?)?,
detailed: lua.from_value(tbl.get("detailed")?)?,
license: lua.from_value(tbl.get("license")?)?,
homepage: lua.from_value(tbl.get("homepage")?)?,
issues_url: lua.from_value(tbl.get("issues_url")?)?,
maintainer: lua.from_value(tbl.get("maintainer")?)?,
labels,
})
}
value => Err(eyre!(format!(
"Could not parse rockspec description. Expected table, but got {}",
value.type_name()
))),
}
}
}

#[derive(Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum PlatformIdentifier {
Unix,
Windows,
Win32,
Cygwin,
MacOSX,
Linux,
FreeBSD,
}

#[cfg(test)]
mod tests {

use super::*;

#[tokio::test]
pub async fn parse_rockspec() {
let rockspec_content = "
rockspec_format = '1.0'\n
package = 'foo'\n
version = '1.0.0-1'\n
"
.to_string();
let rockspec = Rockspec::new(&rockspec_content).unwrap();
assert_eq!(rockspec.rockspec_format, Some("1.0".into()));
assert_eq!(rockspec.package, "foo");
assert_eq!(rockspec.version, "1.0.0-1");
assert_eq!(rockspec.description, RockDescription::default());

let rockspec_content = "
package = 'bar'\n
version = '2.0.0-1'\n
description = {}\n
"
.to_string();
let rockspec = Rockspec::new(&rockspec_content).unwrap();
assert_eq!(rockspec.rockspec_format, None);
assert_eq!(rockspec.package, "bar");
assert_eq!(rockspec.version, "2.0.0-1");
assert_eq!(rockspec.description, RockDescription::default());

let rockspec_content = "
package = 'rocks'\n
version = '3.0.0-1'\n
description = {\n
summary = 'some summary',
detailed = 'some detailed description',
license = 'MIT',
homepage = 'https://github.com/nvim-neorocks/rocks',
issues_url = 'https://github.com/nvim-neorocks/rocks/issues',
maintainer = 'neorocks',
}\n
"
.to_string();
let rockspec = Rockspec::new(&rockspec_content).unwrap();
assert_eq!(rockspec.rockspec_format, None);
assert_eq!(rockspec.package, "rocks");
assert_eq!(rockspec.version, "3.0.0-1");
let expected_description = RockDescription {
summary: Some("some summary".into()),
detailed: Some("some detailed description".into()),
license: Some("MIT".into()),
homepage: Some("https://github.com/nvim-neorocks/rocks".into()),
issues_url: Some("https://github.com/nvim-neorocks/rocks/issues".into()),
maintainer: Some("neorocks".into()),
labels: Vec::new(),
};
assert_eq!(rockspec.description, expected_description);

let rockspec_content = "
package = 'rocks'\n
version = '3.0.0-1'\n
description = {\n
summary = 'some summary',
detailed = 'some detailed description',
license = 'MIT',
homepage = 'https://github.com/nvim-neorocks/rocks',
issues_url = 'https://github.com/nvim-neorocks/rocks/issues',
maintainer = 'neorocks',
labels = {},
}\n
"
.to_string();
let rockspec = Rockspec::new(&rockspec_content).unwrap();
assert_eq!(rockspec.rockspec_format, None);
assert_eq!(rockspec.package, "rocks");
assert_eq!(rockspec.version, "3.0.0-1");
let expected_description = RockDescription {
summary: Some("some summary".into()),
detailed: Some("some detailed description".into()),
license: Some("MIT".into()),
homepage: Some("https://github.com/nvim-neorocks/rocks".into()),
issues_url: Some("https://github.com/nvim-neorocks/rocks/issues".into()),
maintainer: Some("neorocks".into()),
labels: Vec::new(),
};
assert_eq!(rockspec.description, expected_description);

let rockspec_content = "
package = 'rocks'\n
version = '3.0.0-1'\n
description = {\n
summary = 'some summary',
detailed = 'some detailed description',
license = 'MIT',
homepage = 'https://github.com/nvim-neorocks/rocks',
issues_url = 'https://github.com/nvim-neorocks/rocks/issues',
maintainer = 'neorocks',
labels = { 'package management', },
}\n
"
.to_string();
let rockspec = Rockspec::new(&rockspec_content).unwrap();
assert_eq!(rockspec.rockspec_format, None);
assert_eq!(rockspec.package, "rocks");
assert_eq!(rockspec.version, "3.0.0-1");
let expected_description = RockDescription {
summary: Some("some summary".into()),
detailed: Some("some detailed description".into()),
license: Some("MIT".into()),
homepage: Some("https://github.com/nvim-neorocks/rocks".into()),
issues_url: Some("https://github.com/nvim-neorocks/rocks/issues".into()),
maintainer: Some("neorocks".into()),
labels: vec!["package management".into()],
};
assert_eq!(rockspec.description, expected_description);
}
}

0 comments on commit 9fb1545

Please sign in to comment.