LUNE 프로토콜 구조체
Last update - 2025. 9. 5.
개요
LUNE 프로토콜의 핵심 데이터 구조체들을 다룹니다. LUNE 메시지와 헤더 구조, 직렬화 방법 등을 자세히 설명합니다.
LUNE 메시지 구조체
LUNE 메시지
use orbital::r#struct::LUNE;
use orbital::r#struct::header::Header;
use chrono::{DateTime, Utc};
// LUNE 메시지 생성
let mut lune_message = LUNE::new();
// 헤더 설정
lune_message.set_status(200);
lune_message.set_origin("client".to_string());
lune_message.set_nonce("abc123".to_string());
lune_message.set_type("api_request".to_string());
lune_message.set_datetime(Utc::now());
// 바디 설정 (JSON)
let body_data = serde_json::json!({
"path": "/api/users",
"method": "READ",
"params": {}
});
lune_message.set_body(body_data.to_string().into_bytes());
println!("LUNE 메시지: {:?}", lune_message);
LUNE 빌더 패턴
use orbital::r#struct::lune::LuneBuilder;
use chrono::Utc;
let lune_message = LuneBuilder::new()
.status(200)
.origin("server".to_string())
.nonce("xyz789".to_string())
.message_type("response".to_string())
.datetime(Utc::now())
.body(serde_json::json!({
"result": "success",
"data": {"user_id": 123}
}))
.build()?;
println!("빌더로 생성된 LUNE: {:?}", lune_message);
Header 구조체
기본 헤더 사용
use orbital::r#struct::header::{Header, HeaderBuilder};
use chrono::Utc;
// 헤더 빌더 사용
let header = HeaderBuilder::new()
.status(200)
.origin("server".to_string())
.nonce("xyz789".to_string())
.message_type("response".to_string())
.datetime(Utc::now())
.build()?;
// 직접 생성
let mut header = Header::new();
header.set_status(404);
header.set_origin("server".to_string());
header.set_type("error_response".to_string());
println!("헤더 정보: {:?}", header);
커스텀 헤더 필드
use orbital::r#struct::header::Header;
let mut header = Header::new();
// 기본 필드 설정
header.set_status(200);
header.set_origin("api_server".to_string());
header.set_type("user_data".to_string());
// 커스텀 필드 추가
header.set_custom_field("User-Agent", "LUNE-Client/1.0");
header.set_custom_field("Authorization", "Bearer token123");
header.set_custom_field("X-Request-ID", "req_456");
// 커스텀 필드 조회
if let Some(user_agent) = header.get_custom_field("User-Agent") {
println!("User Agent: {}", user_agent);
}
// 모든 커스텀 필드 출력
for (key, value) in header.custom_fields() {
println!("커스텀 헤더: {} = {}", key, value);
}
헤더 필드 상세
표준 헤더 필드
use orbital::r#struct::header::Header;
use chrono::{Utc, DateTime};
let mut header = Header::new();
// Status (u16): HTTP 상태 코드와 유사
header.set_status(200); // 성공
header.set_status(400); // 잘못된 요청
header.set_status(404); // 찾을 수 없음
header.set_status(500); // 서버 오류
// Origin (String): 메시지 발신자
header.set_origin("client".to_string()); // 클라이언트
header.set_origin("server".to_string()); // 서버
header.set_origin("gateway".to_string()); // 게이트웨이
// Nonce (String): 중복 방지를 위한 고유값
header.set_nonce(uuid::Uuid::new_v4().to_string());
header.set_nonce("request_12345".to_string());
// Type (String): 메시지 타입
header.set_type("READ /api/users".to_string());
header.set_type("CREATE /api/posts".to_string());
header.set_type("heartbeat".to_string());
// DateTime (DateTime<Utc>): 메시지 생성 시간
header.set_datetime(Utc::now());
header.set_datetime(DateTime::parse_from_rfc3339("2023-12-01T12:00:00Z")?.with_timezone(&Utc));
// 헤더 정보 출력
println!("Status: {}", header.status());
println!("Origin: {}", header.origin());
println!("Nonce: {}", header.nonce());
println!("Type: {}", header.message_type());
println!("DateTime: {}", header.datetime());
헤더 검증
use orbital::r#struct::header::{Header, HeaderValidationError};
fn validate_header(header: &Header) -> Result<(), HeaderValidationError> {
// 상태 코드 검증
if header.status() == 0 {
return Err(HeaderValidationError::InvalidStatus("Status cannot be zero".to_string()));
}
// Origin 검증
if header.origin().is_empty() {
return Err(HeaderValidationError::EmptyOrigin);
}
// Nonce 검증
if header.nonce().len() < 8 {
return Err(HeaderValidationError::InvalidNonce("Nonce too short".to_string()));
}
// 메시지 타입 검증
if header.message_type().is_empty() {
return Err(HeaderValidationError::EmptyMessageType);
}
// 시간 검증 (너무 오래된 메시지)
let now = chrono::Utc::now();
let age = now.signed_duration_since(header.datetime());
if age.num_minutes() > 5 {
return Err(HeaderValidationError::MessageTooOld(age.num_minutes()));
}
Ok(())
}
// 사용 예시
let mut header = Header::new();
header.set_status(200);
header.set_origin("client".to_string());
header.set_nonce("short".to_string()); // 너무 짧음
header.set_type("test".to_string());
header.set_datetime(chrono::Utc::now());
match validate_header(&header) {
Ok(_) => println!("✅ 헤더 검증 통과"),
Err(e) => eprintln!("❌ 헤더 검증 실패: {:?}", e),
}
메시지 바디 처리
JSON 바디
use orbital::r#struct::LUNE;
use serde_json::{json, Value};
let mut lune_message = LUNE::new();
// JSON 바디 설정
let json_body = json!({
"user": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
},
"action": "update_profile",
"timestamp": chrono::Utc::now().to_rfc3339()
});
lune_message.set_body(json_body.to_string().into_bytes());
// JSON 바디 파싱
let body_bytes = lune_message.body();
let body_str = String::from_utf8(body_bytes.clone())?;
let parsed_json: Value = serde_json::from_str(&body_str)?;
println!("파싱된 JSON: {}", parsed_json);
// 특정 필드 접근
if let Some(user) = parsed_json.get("user") {
if let Some(name) = user.get("name") {
println!("사용자 이름: {}", name);
}
}
바이너리 바디
use orbital::r#struct::LUNE;
let mut lune_message = LUNE::new();
// 바이너리 데이터 설정
let binary_data = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello"
lune_message.set_body(binary_data);
// 바이너리 데이터 읽기
let body = lune_message.body();
let text = String::from_utf8(body.clone())
.unwrap_or_else(|_| format!("Binary data: {} bytes", body.len()));
println!("바디 내용: {}", text);
// 바이너리 데이터 처리
for (i, byte) in body.iter().enumerate() {
println!("Byte {}: 0x{:02X} ({})", i, byte, *byte as char);
}
구조화된 데이터
use orbital::r#struct::LUNE;
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
struct UserRequest {
action: String,
user_id: u64,
data: UserData,
}
#[derive(Debug, Serialize, Deserialize)]
struct UserData {
name: String,
email: String,
age: Option<u32>,
}
// 구조화된 데이터를 LUNE 메시지로 변환
let user_request = UserRequest {
action: "create_user".to_string(),
user_id: 0, // 새 사용자
data: UserData {
name: "Bob".to_string(),
email: "bob@example.com".to_string(),
age: Some(25),
},
};
let mut lune_message = LUNE::new();
let serialized = serde_json::to_string(&user_request)?;
lune_message.set_body(serialized.into_bytes());
// LUNE 메시지에서 구조화된 데이터로 역변환
let body_str = String::from_utf8(lune_message.body().clone())?;
let deserialized: UserRequest = serde_json::from_str(&body_str)?;
println!("역직렬화된 데이터: {:?}", deserialized);
메시지 유틸리티
메시지 복제
use orbital::r#struct::LUNE;
let mut original = LUNE::new();
original.set_status(200);
original.set_origin("client".to_string());
original.set_type("test".to_string());
// 메시지 복제
let mut cloned = original.clone();
// 복제본 수정
cloned.set_status(201);
cloned.set_origin("server".to_string());
println!("원본 상태: {}", original.header().status());
println!("복제본 상태: {}", cloned.header().status());
메시지 비교
use orbital::r#struct::LUNE;
let mut msg1 = LUNE::new();
msg1.set_status(200);
msg1.set_nonce("abc123".to_string());
let mut msg2 = LUNE::new();
msg2.set_status(200);
msg2.set_nonce("abc123".to_string());
// 메시지 비교 (nonce 기준)
fn messages_equal(msg1: &LUNE, msg2: &LUNE) -> bool {
msg1.header().nonce() == msg2.header().nonce()
}
if messages_equal(&msg1, &msg2) {
println!("✅ 메시지가 동일합니다");
} else {
println!("❌ 메시지가 다릅니다");
}
메시지 요약
use orbital::r#struct::LUNE;
impl LUNE {
fn summary(&self) -> String {
format!(
"LUNE[{} {} {} | {} bytes]",
self.header().status(),
self.header().origin(),
self.header().message_type(),
self.body().len()
)
}
fn is_request(&self) -> bool {
self.header().origin() == "client"
}
fn is_response(&self) -> bool {
self.header().origin() == "server"
}
fn is_success(&self) -> bool {
self.header().status() >= 200 && self.header().status() < 300
}
fn is_error(&self) -> bool {
self.header().status() >= 400
}
}
// 사용 예시
let mut message = LUNE::new();
message.set_status(404);
message.set_origin("server".to_string());
message.set_type("error_response".to_string());
message.set_body(b"Not found".to_vec());
println!("메시지 요약: {}", message.summary());
println!("요청 메시지? {}", message.is_request());
println!("응답 메시지? {}", message.is_response());
println!("성공? {}", message.is_success());
println!("에러? {}", message.is_error());
메시지 검증
완전성 검증
use orbital::r#struct::LUNE;
#[derive(Debug)]
enum MessageValidationError {
EmptyNonce,
InvalidStatus,
EmptyType,
EmptyBody,
InvalidTimestamp,
}
fn validate_message(message: &LUNE) -> Result<(), MessageValidationError> {
let header = message.header();
// Nonce 검증
if header.nonce().is_empty() {
return Err(MessageValidationError::EmptyNonce);
}
// 상태 코드 검증
if header.status() == 0 {
return Err(MessageValidationError::InvalidStatus);
}
// 메시지 타입 검증
if header.message_type().is_empty() {
return Err(MessageValidationError::EmptyType);
}
// 바디 검증
if message.body().is_empty() {
return Err(MessageValidationError::EmptyBody);
}
// 타임스탬프 검증 (5분 이내)
let now = chrono::Utc::now();
let age = now.signed_duration_since(header.datetime());
if age.num_minutes().abs() > 5 {
return Err(MessageValidationError::InvalidTimestamp);
}
Ok(())
}
// 검증 예시
let mut message = LUNE::new();
message.set_status(200);
message.set_nonce("valid_nonce".to_string());
message.set_type("test_message".to_string());
message.set_body(b"test data".to_vec());
message.set_datetime(chrono::Utc::now());
match validate_message(&message) {
Ok(_) => println!("✅ 메시지 검증 통과"),
Err(e) => eprintln!("❌ 메시지 검증 실패: {:?}", e),
}
다음 단계
LUNE 프로토콜 구조체에 대해 알아보았다면, 다음 문서들을 확인해보세요: