use std::fs::File;
use std::future::Future;
use std::io::{BufRead, BufReader, Read, Write};
use std::net::{TcpListener, TcpStream, UdpSocket};
use std::pin::Pin;
use std::process::{Child, ChildStdin};
use std::sync::Arc;
use std::time::{Instant, SystemTime};
use parking_lot::Mutex;
use super::value::{Map, MapKey, Value};
pub type BoxFut = Pin<Box<dyn Future<Output = Value> + Send>>;
pub type LineIter = Box<dyn Iterator<Item = std::io::Result<String>> + Send>;
pub enum Native {
Entry {
map: Map,
key: MapKey,
},
Task(tokio::task::JoinHandle<Value>),
Future(BoxFut),
HttpClient(reqwest::Client),
BlockingHttpClient(reqwest::blocking::Client),
Instant(Instant),
SystemTime(SystemTime),
Child(Child),
ChildStdin(ChildStdin),
File(BufReader<File>),
Reader(BufReader<Box<dyn Read + Send>>),
Writer(Box<dyn Write + Send>),
Listener(TcpListener),
Stream(TcpStream),
Udp(UdpSocket),
Pdf(Box<lopdf::Document>),
TempDir(tempfile::TempDir),
NamedTempFile(tempfile::NamedTempFile),
Sha256(sha2::Sha256),
SigningKey(ed25519_dalek::SigningKey),
VerifyingKey(ed25519_dalek::VerifyingKey),
Signature(ed25519_dalek::Signature),
Lines(LineIter),
Body(Vec<u8>),
Regex(super::regex_bridge::RegexValue),
RegexMatch(super::regex_bridge::MatchValue),
RegexCaptures(super::regex_bridge::CapturesValue),
Iterator(super::iterator::IteratorState),
IoErr {
display: String,
debug: String,
kind: String,
code: Option<i32>,
},
ParseErr {
display: String,
debug: String,
},
JoinErr {
display: String,
debug: String,
is_panic: bool,
},
Fmt {
text: String,
padded: bool,
},
Taken,
}
impl Native {
pub fn type_name(&self) -> &'static str {
match self {
Native::Entry { .. } => "Entry",
Native::Task(_) => "JoinHandle",
Native::Future(_) => "Future",
Native::HttpClient(_) | Native::BlockingHttpClient(_) => "Client",
Native::ParseErr { .. } => "ParseError",
Native::Instant(_) => "Instant",
Native::SystemTime(_) => "SystemTime",
Native::Child(_) => "Child",
Native::ChildStdin(_) => "ChildStdin",
Native::File(_) => "File",
Native::Reader(_) => "Reader",
Native::Writer(_) => "Writer",
Native::Listener(_) => "TcpListener",
Native::Stream(_) => "TcpStream",
Native::Udp(_) => "UdpSocket",
Native::Pdf(_) => "PdfDocument",
Native::TempDir(_) => "TempDir",
Native::NamedTempFile(_) => "NamedTempFile",
Native::Sha256(_) => "Sha256",
Native::SigningKey(_) => "SigningKey",
Native::VerifyingKey(_) => "VerifyingKey",
Native::Signature(_) => "Signature",
Native::Lines(_) => "Lines",
Native::Body(_) => "Body",
Native::Regex(_) => "Regex",
Native::RegexMatch(_) => "Match",
Native::RegexCaptures(_) => "Captures",
Native::Iterator(_) => "Iterator",
Native::IoErr { .. } => "IoError",
Native::JoinErr { .. } => "JoinError",
Native::Fmt { .. } => "Formatter",
Native::Taken => "Taken",
}
}
pub fn as_read(&mut self) -> Option<&mut dyn Read> {
match self {
Native::File(r) => Some(r),
Native::Reader(r) => Some(r),
_ => None,
}
}
pub fn as_buf_read(&mut self) -> Option<&mut dyn BufRead> {
match self {
Native::File(r) => Some(r),
Native::Reader(r) => Some(r),
_ => None,
}
}
pub fn wrap(self) -> Value {
Value::Native(Arc::new(Mutex::new(self)))
}
}
pub(super) fn io_error_value(e: &std::io::Error) -> Value {
Native::IoErr {
display: e.to_string(),
debug: format!("{e:?}"),
kind: format!("{:?}", e.kind()),
code: e.raw_os_error(),
}
.wrap()
}