1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) 2021 Paul Miller
// Copyright (c) 2022-2023 Yuki Kishimoto
// Copyright (c) 2023-2024 Rust Nostr Developers
// Distributed under the MIT software license

//! Raw event

use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
use core::str::FromStr;

use bitcoin::secp256k1::schnorr::Signature;
use bitcoin::secp256k1::{self};

use super::{id, tag};
use crate::{key, Event, EventId, JsonUtil, Kind, PartialEvent, PublicKey, Tag, Timestamp};

/// [`RawEvent`] error
#[derive(Debug)]
pub enum Error {
    /// Secp256k1 error
    Secp256k1(secp256k1::Error),
    /// EventId error
    EventId(id::Error),
    /// Keys error
    Keys(key::Error),
    /// Tag error
    Tag(tag::Error),
}

#[cfg(feature = "std")]
impl std::error::Error for Error {}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Secp256k1(e) => write!(f, "Secp256k1: {e}"),
            Self::EventId(e) => write!(f, "Event ID: {e}"),
            Self::Keys(e) => write!(f, "Keys: {e}"),
            Self::Tag(e) => write!(f, "Tag: {e}"),
        }
    }
}

impl From<secp256k1::Error> for Error {
    fn from(e: secp256k1::Error) -> Self {
        Self::Secp256k1(e)
    }
}

impl From<id::Error> for Error {
    fn from(e: id::Error) -> Self {
        Self::EventId(e)
    }
}

impl From<key::Error> for Error {
    fn from(e: key::Error) -> Self {
        Self::Keys(e)
    }
}

impl From<tag::Error> for Error {
    fn from(e: tag::Error) -> Self {
        Self::Tag(e)
    }
}

/// Raw event
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct RawEvent {
    /// ID
    pub id: String,
    /// Author
    pub pubkey: String,
    /// Timestamp (seconds)
    pub created_at: u64,
    /// Kind
    pub kind: u64,
    /// Vector of strings
    pub tags: Vec<Vec<String>>,
    /// Content
    pub content: String,
    /// Signature
    pub sig: String,
}

impl JsonUtil for RawEvent {
    type Err = serde_json::Error;
}

impl TryFrom<RawEvent> for Event {
    type Error = Error;

    fn try_from(raw: RawEvent) -> Result<Self, Self::Error> {
        let id: EventId = EventId::from_hex(raw.id)?;
        let public_key: PublicKey = PublicKey::from_hex(raw.pubkey)?;
        let created_at: Timestamp = Timestamp::from(raw.created_at);
        let kind: Kind = Kind::from(raw.kind);
        let tags: Vec<Tag> = raw
            .tags
            .into_iter()
            .map(Tag::parse)
            .collect::<Result<Vec<_>, _>>()?;
        let sig: Signature = Signature::from_str(&raw.sig)?;
        Ok(Self::new(
            id,
            public_key,
            created_at,
            kind,
            tags,
            raw.content,
            sig,
        ))
    }
}

impl TryFrom<&RawEvent> for PartialEvent {
    type Error = Error;

    fn try_from(raw: &RawEvent) -> Result<Self, Self::Error> {
        let id: EventId = EventId::from_hex(&raw.id)?;
        let public_key: PublicKey = PublicKey::from_hex(&raw.pubkey)?;
        let sig: Signature = Signature::from_str(&raw.sig)?;
        Ok(Self {
            id,
            pubkey: public_key,
            sig,
        })
    }
}