use alloc::string::String;
use core::{fmt::Debug, marker::PhantomData};
use std::fs::create_dir_all;
use grammartec::{chunkstore::ChunkStore, context::Context};
use serde::{Deserialize, Serialize};
use serde_json;
use crate::{
bolts::tuples::Named,
corpus::{Corpus, Testcase},
events::EventFirer,
executors::ExitKind,
feedbacks::Feedback,
generators::NautilusContext,
inputs::{NautilusInput, UsesInput},
observers::ObserversTuple,
state::{HasClientPerfMonitor, HasCorpus, HasMetadata},
Error,
};
#[derive(Serialize, Deserialize)]
pub struct NautilusChunksMetadata {
pub cks: ChunkStore,
}
impl Debug for NautilusChunksMetadata {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"NautilusChunksMetadata {{ {} }}",
serde_json::to_string_pretty(self).unwrap(),
)
}
}
crate::impl_serdeany!(NautilusChunksMetadata);
impl NautilusChunksMetadata {
#[must_use]
pub fn new(work_dir: String) -> Self {
create_dir_all(format!("{}/outputs/chunks", &work_dir))
.expect("Could not create folder in workdir");
Self {
cks: ChunkStore::new(work_dir),
}
}
}
pub struct NautilusFeedback<'a, S> {
ctx: &'a Context,
phantom: PhantomData<S>,
}
impl<S> Debug for NautilusFeedback<'_, S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "NautilusFeedback {{}}")
}
}
impl<'a, S> NautilusFeedback<'a, S> {
#[must_use]
pub fn new(context: &'a NautilusContext) -> Self {
Self {
ctx: &context.ctx,
phantom: PhantomData,
}
}
}
impl<'a, S> Named for NautilusFeedback<'a, S> {
fn name(&self) -> &str {
"NautilusFeedback"
}
}
impl<'a, S> Feedback<S> for NautilusFeedback<'a, S>
where
S: HasMetadata
+ HasClientPerfMonitor
+ UsesInput<Input = NautilusInput>
+ HasCorpus<Input = NautilusInput>,
{
#[allow(clippy::wrong_self_convention)]
fn is_interesting<EM, OT>(
&mut self,
_state: &mut S,
_manager: &mut EM,
_input: &NautilusInput,
_observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<State = S>,
OT: ObserversTuple<S>,
{
Ok(false)
}
fn append_metadata<OT>(
&mut self,
state: &mut S,
_observers: &OT,
testcase: &mut Testcase<S::Input>,
) -> Result<(), Error>
where
OT: ObserversTuple<S>,
{
state.corpus().load_input_into(testcase)?;
let input = testcase.input().as_ref().unwrap().clone();
let meta = state
.metadata_map_mut()
.get_mut::<NautilusChunksMetadata>()
.expect("NautilusChunksMetadata not in the state");
meta.cks.add_tree(input.tree, self.ctx);
Ok(())
}
fn discard_metadata(&mut self, _state: &mut S, _input: &NautilusInput) -> Result<(), Error> {
Ok(())
}
}