Skip to main content

provenant/output_schema/
license_match.rs

1// SPDX-FileCopyrightText: Provenant contributors
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::models::MatchScore;
5use serde::{Deserialize, Serialize};
6
7#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
8pub struct OutputMatch {
9    pub license_expression: String,
10    pub license_expression_spdx: String,
11    pub from_file: Option<String>,
12    pub start_line: u64,
13    pub end_line: u64,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub matcher: Option<String>,
16    pub score: MatchScore,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub matched_length: Option<usize>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub match_coverage: Option<f64>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub rule_relevance: Option<u8>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub rule_identifier: Option<String>,
25    pub rule_url: Option<String>,
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub matched_text: Option<String>,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub matched_text_diagnostics: Option<String>,
30    #[serde(skip_serializing_if = "Option::is_none", default)]
31    pub referenced_filenames: Option<Vec<String>>,
32}
33
34impl From<&crate::models::Match> for OutputMatch {
35    fn from(value: &crate::models::Match) -> Self {
36        Self {
37            license_expression: value.license_expression.clone(),
38            license_expression_spdx: value.license_expression_spdx.clone(),
39            from_file: value.from_file.clone(),
40            start_line: value.start_line.get() as u64,
41            end_line: value.end_line.get() as u64,
42            matcher: value.matcher.clone(),
43            score: value.score,
44            matched_length: value.matched_length,
45            match_coverage: value.match_coverage,
46            rule_relevance: value.rule_relevance,
47            rule_identifier: value.rule_identifier.clone(),
48            rule_url: value.rule_url.clone(),
49            matched_text: value.matched_text.clone(),
50            matched_text_diagnostics: value.matched_text_diagnostics.clone(),
51            referenced_filenames: value.referenced_filenames.clone(),
52        }
53    }
54}
55
56impl TryFrom<&OutputMatch> for crate::models::Match {
57    type Error = String;
58    fn try_from(value: &OutputMatch) -> Result<Self, Self::Error> {
59        use crate::models::LineNumber;
60        let start_line = LineNumber::new(value.start_line as usize)
61            .ok_or_else(|| format!("invalid start_line: {}", value.start_line))?;
62        let end_line = LineNumber::new(value.end_line as usize)
63            .ok_or_else(|| format!("invalid end_line: {}", value.end_line))?;
64        Ok(Self {
65            license_expression: value.license_expression.clone(),
66            license_expression_spdx: value.license_expression_spdx.clone(),
67            from_file: value.from_file.clone(),
68            start_line,
69            end_line,
70            matcher: value.matcher.clone(),
71            score: value.score,
72            matched_length: value.matched_length,
73            match_coverage: value.match_coverage,
74            rule_relevance: value.rule_relevance,
75            rule_identifier: value.rule_identifier.clone(),
76            rule_url: value.rule_url.clone(),
77            matched_text: value.matched_text.clone(),
78            matched_text_diagnostics: value.matched_text_diagnostics.clone(),
79            referenced_filenames: value.referenced_filenames.clone(),
80        })
81    }
82}