ligen_python_parser/parser/
metadata.rs1use ligen::parser::ParserConfig;
2use ligen::ir::{Metadata, Version, VersionRequirement, Author, Dependency, Language};
3
4use crate::prelude::*;
5
6#[derive(Default)]
7pub struct MetadataParser {}
8
9impl MetadataParser {
10 pub fn new() -> Self {
11 Default::default()
12 }
13}
14
15impl Parser<python_pkginfo::Metadata> for MetadataParser {
16 type Output = Metadata;
17 fn parse(&self, input: python_pkginfo::Metadata, _config: &ParserConfig) -> Result<Self::Output> {
18 let version = Version::try_from(input.version.as_str())?;
19 let requirement = VersionRequirement::from(input.requires_python.unwrap_or_default().as_str());
20 let language = Language { name: "Python".into(), requirement };
21 let homepage = input.home_page.unwrap_or_default();
22 let summary = input.summary.unwrap_or_default();
23 let description = input.description.unwrap_or_default();
24 let keywords = input.keywords.unwrap_or_default().split(',').map(String::from).collect();
25 let authors = vec![Author::new(input.author.unwrap_or_default(), input.author_email.unwrap_or_default())];
26 let license = input.license.unwrap_or_default();
27 let mut dependencies = Vec::new();
28 for requirement in input.requires_dist {
29 let requirement = Dependency::try_from(requirement.as_str())?;
30 dependencies.push(requirement);
31 }
32 Ok(Self::Output { version, authors, dependencies, keywords, description, language, homepage, summary, license })
33 }
34}
35
36impl Parser<&std::path::Path> for MetadataParser {
37 type Output = Metadata;
38 fn parse(&self, input: &std::path::Path, config: &ParserConfig) -> Result<Self::Output> {
39 let name = input.file_name().ok_or("Failed to get file name.")?;
40 let name = name.to_string_lossy().to_string();
41 let input = input.parent().ok_or("Failed to get parent.")?;
42 let dir = input.read_dir()?;
43 let dist_info_dir = dir
44 .filter_map(|entry| entry.ok())
45 .find(|entry| {
46 let file_name = entry
47 .file_name()
48 .to_string_lossy()
49 .to_string();
50 file_name.starts_with(&name) && file_name.ends_with(".dist-info")
51 });
52 let dist_info_dir = dist_info_dir.ok_or(format!("Failed to find dist-info directory for `{}`", name))?;
53 let metadata_file = dist_info_dir
54 .path()
55 .join("METADATA");
56 let content = std::fs::read_to_string(metadata_file)?;
57 let metadata = python_pkginfo::Metadata::parse(content.as_bytes())
58 .map_err(|e| Error::Message(format!("Failed to parse metadata: {}", e)))?;
59 self.parse(metadata, config)
60 }
61}