use serde::{Deserialize, Serialize};
use super::super::{DomainError, GraphVersion, RepositoryCodeRange, error::required_text};
use super::validation::{normalize_optional, stable_software_id, validate_confidence};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SoftwareFile {
pub software_file_id: String,
pub repository_id: String,
pub source_scope: String,
pub path: String,
pub language_id: String,
pub file_role: String,
pub parse_status: String,
pub created_graph_version: GraphVersion,
}
impl SoftwareFile {
pub fn new(input: SoftwareFileInput) -> Result<Self, DomainError> {
let source_scope = required_text("source_scope", input.source_scope)?;
let path = required_text("software_file_path", input.path)?;
Ok(Self {
software_file_id: stable_software_id("file", [source_scope.as_str(), path.as_str()]),
repository_id: required_text("repository_id", input.repository_id)?,
source_scope,
path,
language_id: required_text("language_id", input.language_id)?,
file_role: required_text("file_role", input.file_role)?,
parse_status: required_text("parse_status", input.parse_status)?,
created_graph_version: input.created_graph_version,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SoftwareFileInput {
pub repository_id: String,
pub source_scope: String,
pub path: String,
pub language_id: String,
pub file_role: String,
pub parse_status: String,
pub created_graph_version: GraphVersion,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SoftwareTopic {
pub topic_id: String,
pub repository_id: String,
pub source_scope: String,
pub name: String,
pub topic_kind: String,
pub source_path: String,
pub line_range: RepositoryCodeRange,
pub created_graph_version: GraphVersion,
}
impl SoftwareTopic {
pub fn new(input: SoftwareTopicInput) -> Result<Self, DomainError> {
let source_scope = required_text("source_scope", input.source_scope)?;
let name = required_text("topic_name", input.name)?;
let topic_kind = required_text("topic_kind", input.topic_kind)?;
let source_path = required_text("topic_source_path", input.source_path)?;
let line_start = input.line_range.start.to_string();
Ok(Self {
topic_id: stable_software_id(
"topic",
[
source_scope.as_str(),
topic_kind.as_str(),
source_path.as_str(),
name.as_str(),
line_start.as_str(),
],
),
repository_id: required_text("repository_id", input.repository_id)?,
source_scope,
name,
topic_kind,
source_path,
line_range: input.line_range,
created_graph_version: input.created_graph_version,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SoftwareTopicInput {
pub repository_id: String,
pub source_scope: String,
pub name: String,
pub topic_kind: String,
pub source_path: String,
pub line_range: RepositoryCodeRange,
pub created_graph_version: GraphVersion,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SoftwareRelationship {
pub relationship_id: String,
pub repository_id: String,
pub source_scope: String,
pub relationship_kind: String,
pub source_id: String,
pub source_kind: String,
pub target_id: String,
pub target_kind: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub target_hint: Option<String>,
pub resolution_state: String,
pub confidence_basis_points: u16,
pub confidence_tier: String,
pub evidence_path: String,
pub evidence_line_range: RepositoryCodeRange,
pub created_graph_version: GraphVersion,
}
impl SoftwareRelationship {
pub fn new(input: SoftwareRelationshipInput) -> Result<Self, DomainError> {
let source_scope = required_text("source_scope", input.source_scope)?;
let relationship_kind = required_text("relationship_kind", input.relationship_kind)?;
let source_id = required_text("relationship_source_id", input.source_id)?;
let target_id = required_text("relationship_target_id", input.target_id)?;
let evidence_path = required_text("evidence_path", input.evidence_path)?;
let line_start = input.evidence_line_range.start.to_string();
Ok(Self {
relationship_id: stable_software_id(
"relationship",
[
source_scope.as_str(),
relationship_kind.as_str(),
source_id.as_str(),
target_id.as_str(),
evidence_path.as_str(),
line_start.as_str(),
],
),
repository_id: required_text("repository_id", input.repository_id)?,
source_scope,
relationship_kind,
source_id,
source_kind: required_text("relationship_source_kind", input.source_kind)?,
target_id,
target_kind: required_text("relationship_target_kind", input.target_kind)?,
target_hint: normalize_optional("target_hint", input.target_hint)?,
resolution_state: required_text("resolution_state", input.resolution_state)?,
confidence_basis_points: validate_confidence(input.confidence_basis_points)?,
confidence_tier: required_text("confidence_tier", input.confidence_tier)?,
evidence_path,
evidence_line_range: input.evidence_line_range,
created_graph_version: input.created_graph_version,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SoftwareRelationshipInput {
pub repository_id: String,
pub source_scope: String,
pub relationship_kind: String,
pub source_id: String,
pub source_kind: String,
pub target_id: String,
pub target_kind: String,
pub target_hint: Option<String>,
pub resolution_state: String,
pub confidence_basis_points: u16,
pub confidence_tier: String,
pub evidence_path: String,
pub evidence_line_range: RepositoryCodeRange,
pub created_graph_version: GraphVersion,
}
#[cfg(test)]
#[path = "graph_tests.rs"]
mod tests;