IndexingData 라는 러스트 구조체를 정의해보겠습니다.
이 구조체는 검색 인덱싱과 관련된 데이터를 표현하기 위한 것입니다.
기본구조
pub struct IndexingData {
// 필드들...
}
여기서, pub 키워드는 이 구조체가 공개되어 있어 다른 모듈에서도 접근할 수 있음을 의미합니다.
먼저 완성된 구조체를 보여드리겠습니다.
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
pub struct IndexingData {
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub index: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schKwdNm: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub schKwdNmArray: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sendGb: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub documentId: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub recomword: Option<String>,
#[serde(flatten)]
pub extra: HashMap<String, serde_json::Value>,
}
Serde 속성
#[serde(skip_serializing_if = "Option::is_none")]
- 모든 필드(extra 제외)에 적용된 이 속성은 해당 필드가 None 일 경우 직렬화 과정에서 이 필드를 완전히 생략하라는 의미입니다.
- 예를 들어, id가 None 이면 JSON으로 변환할 때 "id": null 이 아니라 id 자체가 출력되지 않습니다.
- 이는 API 응답이나 JSON 문서를 더 간결하게 만들고, 불필요한 null 값을 피하는 데 유용합니다.
#[serde(flatten)]
- extra 필드에 적용된 이 속성은 해시맵의 내용을 구조체의 최상위 레벨로 "펼쳐서" 직렬화/역직렬화 하라는 의미입니다.
- 이는 구조체에 명시적으로 정의되지 않은 추가 필드들을 유연하게 처리할 수 있게 해줍니다.
- 예를 들어, JSON에 {"id": "123", "unknown_field": "value"}가 있다면, id는 구조체의 id 필드에 매핑되고, unknown_field는 extra 해시맵에 저장됩니다.
이 구조체를 사용하는 예시 코드입니다.
let indexing_data = IndexingData {
id: Some("doc123".to_string()),
index: Some("products".to_string()),
schKwdNm: Some("스마트폰".to_string()),
schKwdNmArray: Some(vec!["스마트폰".to_string(), "휴대폰".to_string()]),
sendGb: None,
documentId: Some("product-123".to_string()),
recomword: None,
extra: [
("priority".to_string(), serde_json::json!(5)),
("category".to_string(), serde_json::json!("electronics")),
].iter().cloned().collect(),
};
// JSON으로 직렬화
let json = serde_json::to_string_pretty(&indexing_data).unwrap();
println!("{}", json);
이 코드의 JSON 출력은 다음과 같을 것입니다.
{
"id": "doc123",
"index": "products",
"schKwdNm": "스마트폰",
"schKwdNmArray": ["스마트폰", "휴대폰"],
"documentId": "product-123",
"priority": 5,
"category": "electronics"
}
sendGb 와 recomword는 None 이므로 출력에 포함되지 않았고, extra 해시맵의 내용은 최상위 레벨에 펼쳐져 있습니다.
'Backend(Framework) > Rust' 카테고리의 다른 글
[Rust] 응답 객체 패턴: ResponseDto 구현 (0) | 2025.03.25 |
---|---|
#[derive(...)] : 러스트의 매크로 속성 (0) | 2025.03.25 |
러스트(Rust) 웹 개발의 핵심 라이브러리 소개 (0) | 2025.03.25 |